我经常在代码中看到这一点:var me = this;
。这是为什么?如果我参考这个'是否有一些性能提升?在局部变量?
答案 0 :(得分:9)
如果 in 函数中的函数很有用,那么这些嵌套函数中的代码需要从外部上下文中访问this
的值。
function example() {
var me = this;
document.getElementById('whatever').onclick = function() {
me.clicked = 1;
};
}
因为this
是为每个函数调用重新建立的,所以如果没有在变量中隐藏外部this
,就无法从内部函数中引用它。
答案 1 :(得分:4)
这用于保存对this
的引用。稍后在代码中有一个带回调的AJAX调用(例如)。因此,回调内部this
与外部不同。这就是为什么人们将“外部”this
备份到变量。
我个人喜欢使用这种形式:
var that = this;
看起来很有趣:)
顺便说一句,CoffeeScript,这是一种“正确的javascript”,也有解决方法。
它有两种形式的功能定义,细箭头和胖箭头。细箭头的行为与javascript完全相同,胖箭头会自动将this
绑定到外部上下文中的值。
所以,这个coffeescript
Account = (customer, cart) -> # thin arrow
@customer = customer
@cart = cart
$('.shopping_cart').bind 'click', (event) => # fat arrow
@customer.purchase @cart
转换为此javascript
var Account;
Account = function(customer, cart) {
var _this = this;
this.customer = customer;
this.cart = cart;
return $('.shopping_cart').bind('click', function(event) {
return _this.customer.purchase(_this.cart);
});
};
很酷,不是吗?
答案 2 :(得分:1)
当this
发生更改时,您仍然需要在代码中指向this
。
答案 3 :(得分:1)
IMO它不寻常你自己看到它 - 当有关闭时,它几乎总是被用来避免JS对{{1}的处理} value,在执行期间评估,而不是声明。
答案 4 :(得分:1)
这通常用于回调方法,其中回调运行时范围会有所不同。
示例:
var me = this;
$.getJSON(url, function(data) {
// here "this" will be "window", so "me" is used to access the object
})
答案 5 :(得分:1)
通常的原因是代码包含一个稍后会被调用的闭包,并且作者希望确保闭包可以访问当前的this
。例如:
这是人们经常写错的代码,如下所示:
var obj = {
name: "Fred",
foo: function() {
setTimeout(function() {
alert(this.name); // <=== Fails, `this` is no longer `obj`
}, 1000);
}
};
obj.foo();
这是var me = this;
适用于它:
var obj = {
name: "Fred",
foo: function() {
var me = this;
setTimeout(function() {
alert(me.name); // <=== Works now
}, 1000);
}
};
obj.foo();
这是因为在JavaScript中,this
完全由如何调用函数定义,而不是定义函数的位置。
更多阅读(披露:两者都是我博客的链接):
答案 6 :(得分:0)
这是关闭范围。看看这两个jQuery插件的区别:
$.fn.blinkClosure = function() {
var jQueryMonad = this, toggleClass = this.toggleClass;
setInterval(function() {
toggleClass.apply(jQueryMonad, ['invisible']);
}, 500);
};
问题在于setInterval
。当调用setInterval
中的函数时,它会启动一个新的执行链,并且该链中的this
绑定到window
。在闭包示例中,我们在jQueryMonad
(或代码中的me
)中保留对我们应用插件的jQuery对象的引用。这样,我们就可以在javascript中保持我们的范围正确。
$.fn.blink = function() {
setInterval($.proxy(function() {
this.toggleClass('invisible');
}, this), 500);
};
在第二个示例中,jQuery.proxy
为您处理。
这是为了解决javascript在执行时绑定this
而不是创建时间的问题。
答案 7 :(得分:0)
它与内部函数一起使用。如您所知,您可以在对象构造函数中使用函数,函数内部可以有函数。如果你看到下面的代码。
function Circle(radius){
this.radius=radius;
this.getArea=function(){
var changeRadius=function(){
this.radius=20; //here this points to global
}
changeRadius();
return Math.PI*Math.pow(this.radius, 2);
}
}
var cd= new Circle(10);
console.log(cd.getArea());
当你调用getArea()时,你将根据半径10获得区域。虽然你在内部函数changeRadius中调用changeRadius(),但是这开始指向全局对象而不是你创建的对象。你可以使用var self=this construct
来解决这个问题。
所以为了解决这种情况,我们可以进行以下更改。
function Circle(radius){
var self=this;
this.radius=radius;
this.getArea=function(){
var changeRadius=function(){
self.radius=20;
}
changeRadius();
return Math.PI*Math.pow(this.radius, 2);
}
}
var cd= new Circle(10);
console.log(cd.getArea());