我有一个问题,我创建的对象看起来像这样:
var myObject = {
AddChildRowEvents: function(row, p2) {
if(document.attachEvent) {
row.attachEvent('onclick', function(){this.DoSomething();});
} else {
row.addEventListener('click', function(){this.DoSomething();}, false);
}
},
DoSomething: function() {
this.SomethingElse(); //<-- Error here, object 'this' does not support this method.
}
}
Run Code Online (Sandbox Code Playgroud)
问题是当我进入'DoSomething'函数时,'this'不会引用'myObject'我做错了什么?
Mik*_*tor 36
当函数被调用时,"this"指的是行.如果你想拥有这个对象,你可以这样做:]
AddChildRowEvents: function(row, p2) {
var theObj = this;
if(document.attachEvent) {
row.attachEvent('onclick', function(){theObj.DoSomething();});
} else {
row.addEventListener('click', function(){theObj.DoSomething();}, false);
}
},
Run Code Online (Sandbox Code Playgroud)
调用该函数时,它可以访问定义函数时在范围内的变量theobj.
svi*_*nto 10
this总是指内部函数,如果你有嵌套函数,你必须创建另一个变量并指向它this.
var myObject = {
AddChildRowEvents: function(row, p2) {
var that = this;
if(document.attachEvent) {
row.attachEvent('onclick', function(){that.DoSomething();});
} else {
row.addEventListener('click', function(){that.DoSomething();}, false);
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题来自thisJS 中的管理方式,可以很快,尤其是当您异步调用回调时(并且在创建闭包时,绑定到此)。
当调用 AddChildRowEvents 方法时,会this很好地引用变量myObject。但是这个方法的目的是为点击放置一个处理程序。所以该事件将在未来的某个时间触发。那个时候,什么对象会真正触发事件?事实上,它是DOM element用户将点击的。所以this将引用这个DOM element而不是myObject变量。
对于比提供的解决方案更现代的解决方案,可以使用bind method或arrow function。
let handler = {
addEventHandler: function(row) {
console.log("this", this)
row.addEventListener("click", () => {
console.log("this", this)
this.doSomethingElse()
})
},
doSomethingElse: function() {
console.log("something else")
}
}
var div = document.querySelector("div")
handler.addEventHandler(div)Run Code Online (Sandbox Code Playgroud)
<div>one</div>Run Code Online (Sandbox Code Playgroud)
使用arrow function(自 以来可用ES2015),this上下文不是执行上下文,而是词法上下文。两者之间的区别在于词法上下文是在构建时而不是在执行时找到的,因此词法上下文更容易跟踪。这里,内侧的arrow function,this引用相同的this外部功能(即,addEventHandler),以便参考myObject。
有关胖箭头函数与常规函数的属性的更多说明:https : //dmittripavlutin.com/6-ways-to-declare-javascript-functions/
let handler = {
addEventHandler: function(row) {
console.log("this", this)
row.addEventListener("click", function() {
console.log("this", this)
this.doSomethingElse()
}.bind(this))
},
doSomethingElse: function() {
console.log("something else")
}
}
var div = document.querySelector("div")
handler.addEventHandler(div)Run Code Online (Sandbox Code Playgroud)
<div>one</div>Run Code Online (Sandbox Code Playgroud)
这一次,当回调函数传递给 时addEventListener,已经将this上下文绑定到this外部addEventHandler函数中的元素。