'var that = this;'JavaScript的意思?

在一个JavaScript文件中,我看到:

function Somefunction(){
var that = this;
...
}

声明that并将this赋值给它的目的是什么?

142112 次浏览

Crockford

按照惯例,我们创建一个private 变量。这是用来制作 对象对私有对象可用 方法。这是一个变通方法 错误在ECMAScript语言 规范,它导致

.内部函数设置错误

JS提琴

function usesThis(name) {
this.myName = name;


function returnMe() {
return this;        //scope is lost because of the inner function
}


return {
returnMe : returnMe
}
}


function usesThat(name) {
var that = this;
this.myName = name;


function returnMe() {
return that;            //scope is baked in with 'that' to the "class"
}


return {
returnMe : returnMe
}
}


var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
"UsesThis thinks it's called " + usesthis.returnMe().myName);

这个警报……

UsesThat认为它叫Dave

UsesThis认为它是未定义的

我将以一个例子开始回答这个问题:

var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
// this is a reference to the element clicked on


var that = this;


colours.forEach(function() {
// this is undefined
// that is a reference to the element clicked on
});
});

我的答案最初用jQuery演示了这一点,这只是略有不同:

$('#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允许您仍然访问this的原始值。

就我个人而言,我不喜欢使用that作为别名。它指的是什么并不明显,特别是如果函数的长度超过几行。我总是使用一个更具描述性的别名。在上面的例子中,我可能会使用clickedEl

这是一种让内部函数(在其他函数中定义的函数)工作得更正常的方法。在javascript中,当你在另一个函数中定义一个函数时,this自动被设置为全局作用域。这可能会令人困惑,因为您希望this具有与外部函数相同的值。

var car = {};
car.starter = {};


car.start = function(){
var that = this;


// you can access car.starter inside this method with 'this'
this.starter.active = false;


var activateStarter = function(){
// 'this' now points to the global scope
// 'this.starter' is undefined, so we use 'that' instead.
that.starter.active = true;


// you could also use car.starter, but using 'that' gives
// us more consistency and flexibility
};


activateStarter();


};

当你创建一个函数作为一个对象的方法(如例子中的car.start),然后在该方法中创建一个函数(如activateStarter)时,这是一个特别的问题。在顶层方法中,this指向对象,它是的方法(在本例中为car),但在内部函数中,this现在指向全局作用域。这是一种痛苦。

在这两个作用域中创建一个按照约定使用的变量是javascript中这个非常普遍问题的解决方案(尽管它在jquery函数中也很有用)。这就是为什么使用非常普通的名字that。这是一种很容易识别的习惯,用来克服语言中的缺点。

就像El Ronnoco暗示的道格拉斯Crockford认为这是一个好主意。

有时this可以引用另一个作用域并引用其他东西,例如,假设你想在DOM事件中调用构造函数方法,在这种情况下,this将引用DOM元素而不是创建的对象。

超文本标记语言

<button id="button">Alert Name</button>

JS

var Person = function(name) {
this.name = name;
var that = this;
this.sayHi = function() {
alert(that.name);
};
};


var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad

< a href = " http://jsbin.com/degaja/1/ " rel =“nofollow”>演示< / >

上面的解决方案将this传递给that,然后我们可以从that访问sayHi方法中的name属性,因此可以在DOM调用中毫无问题地调用它。

另一种解决方案是分配一个空that对象,并向其添加属性和方法,然后返回它。但是这个解决方案丢失了构造函数的prototype

var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};

如果你使用call()apply()来解决问题,that的使用其实是不必要的:

var car = {};
car.starter = {};


car.start = function(){
this.starter.active = false;


var activateStarter = function(){
// 'this' now points to our main object
this.starter.active = true;
};


activateStarter.apply(this);
};

这里有一个例子 ' < / p >

$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();


var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
var imgAlt = $(this).find('img').attr('alt'); //Here value of "this" is '.our-work-single-page'.
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}


});
});`

因此,您可以看到this的值是两个不同的值,这取决于您的目标DOM元素,但当您在上面的代码中添加“that”时,您更改了您所瞄准的“this”的值。

`$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();
var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
var that = this;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
***$(that).css("background-color", "#ffe700");*** //Here value of "that" is ".our-work-group > p > a"....
var imgAlt = $(this).find('img').attr('alt');
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}


});
});`

< em >(美元). css(“背景颜色”,“# ffe700”);< / em > //这里的"that" is "的值。Our-work-group > p > a"因为var that = this的值;所以即使我们在"this"= '。we -work-single-page’,我们仍然可以使用“that”来操作前面的DOM元素。