我理解JavaScript会自动为每个函数/方法分配参数this
,并且this
绑定到包含它的对象。
方法是存储为对象属性的函数。因此,在方法中,this
可用于修改或从包含它的对象中检索值。但是,如果将该方法作为函数调用,而不是作为对象的属性调用,那么this
将绑定到全局,而不是绑定到对象。
解决方法是分配:
var that = this;
在方法内部,以便内部函数可以通过变量this
访问that
。
我的问题是:为什么这种解决方法是必要的?你不能一直使用方法吗?为什么你会调用一个非常好的方法作为内部函数,然后必须创建另一个变量,以便它具有它作为一个方法被调用时的访问权限?
我必须在这里遗漏一些重要的东西,如果有一个愚蠢的问题标签,我会用它。 (有人可以制作吗?)
答案 0 :(得分:2)
我希望我理解你的问题。因为你说它的方式有点心思f *** XD。
但是从我的理解。我将回答你的问题,如“我们使用that
技巧做什么?”。
所以这是一个非常健康的对象。
var myobject = {
firstMethod : function(){
this.secoundMethod(); // calls the other method
},
scoundMethod : function(){
return 'hi from method 2' ;
}
}
现在我想做一些jquery魔术(或任何其他具有回调功能的东西)。 我将使用jQuery但随意做其他事情。
var myobject = {
firstMethod : function(){
var _this = this ;
this.secoundMethod(); // calls the other method
$('.myClass').animate({'width':300} , 300 , function(){
// this is a call back functon which will be called as soon as the animation ends
// the problem is that if i call @var : `this` , it wont work because im in
// another scope other than the firstMethod .
// so the following will throw an error .
this.secoundMethod(); // error
// to solve this you need the @var : `that` , or in my case i love it to be _this
_this.scoundMethod() // this will work .
})
},
scoundMethod : function(){
return 'hi from method 2' ;
}
}
所以主要是_this
(在我的例子中)用来限定事物的范围。所以我可以访问其他范围内的对象范围。
说实话,我在其他地方使用过这个技巧(在99%的情况下);
即使剩下的1%基本上是相同的想法,但有更深的嵌套或许多闭包和类似的东西。
这取决于你有多聪明。这是另一个大脑的例子
var myobject = {
firstMethod : function(){
var _this = this ,
someObject : {
firstMethod : function(){
this.scoundMethod(); // if you log this you will get 'the wrong method'.
_this.scoundMethod(); // in here you get 'hi from method 2'.
},
scoundMethod : function(){
return 'the wrong method';
}
};
},
scoundMethod : function(){
return 'hi from method 2' ;
}
}
正如你所看到的那样,这很危险,不是因为它不起作用,而是因为它起作用的恐惧。因为如果你有类似命名的功能,并且你有一个错过的范围,你最终会花费数小时的时间进行挖掘。如果你没有那个...你会得到一个很好的错误,你可以立即修复
你可以随心所欲地筑巢吗?但有后果(很少啊?!)。 享受以下,不要尝试在家里。
var myobject = {
firstMethod : function(){
var _this = this ,
someVar = [1 , 2 , 3 ] ;
this.scoundMethod(function(){
var that = this;
$.each(someVar,function(elementName){
var them = this;
$('.'+elementName).animate({} , 300 , function(){
console.log(them) // logs the element
console.log(_this.scoundMethod()) // logs 'hi from method 2'
})
})
}
},
scoundMethod : function(){
return 'hi from method 2' ;
}
}
“this” and “that”: understanding execution context in javascript - by stevenmhunt
希望我简单明了。而且我没有回答错误的问题。
答案 1 :(得分:2)
this
和that
的问题已经得到了雄辩和简洁的回答elsewhere,所以我会回答你的问题:为什么要调用内部函数?
使用链接的答案作为跳出点:
$('#element').click(function(){
// this is a reference to the element clicked on
var that = this;
$('.elements').each(function(){
// this is a reference to the current element in the loop
// that is still a reference to the element clicked on
});
});
实例化一个新对象,传入你需要的所有变量,并手动构建适当的环境只是为了遍历一些元素,会带来什么好处?您拥有适当的环境,范围正是您需要的地方。
如果您需要访问内部范围内的this
变量,则需要重新分配它,因为它在内部范围内被重新使用。
在这种情况下,有些人使用that
,这在我看来并不是很有启发性,但这只是将范围传递给这些非常有用的临时内部范围的方法。
这真的是关键,它是临时范围的变化。当你在这里完成时,没有理由创建一个全新的范围,符号表等等。
答案 2 :(得分:2)
事件和计时器中回调的执行上下文更改。所以它的价值就变成了窗口。
将此分配给那个(或自我)''成为可以通过闭包访问的变量。 'that'给回调提供'this'。
谷歌的一些东西:javascript闭包,执行上下文,javascript自我,javascript计时器/事件上下文。
答案 3 :(得分:0)
其中一个原因是,如果您将其设置为上下文,则可能需要call
或apply
该方法。
var obj = { name: 'foo' }, logger = function (name) { this.name = name; this.log = function () { console.log(this.name) } }; var bar = new logger('bar'); bar.log(); // -> 'bar' bar.log.call(obj); // -> 'foo'