在我看到的 JavaScript 文件中:
function Somefunction(){
var that = this;
...
}
声明that
并将其分配this
给它的目的是什么?
在我看到的 JavaScript 文件中:
function Somefunction(){
var that = this;
...
}
声明that
并将其分配this
给它的目的是什么?
我将用一个插图开始这个答案:
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
通过调用新函数更改作用域时经常会发生变化,所以无法通过使用它来访问原始值。将其别名为 tothat
允许您仍然访问this
.
就个人而言,我不喜欢使用that
as 别名。它所指的内容很少是显而易见的,尤其是当函数长度超过几行时。我总是使用更具描述性的别名。在我上面的例子中,我可能会使用clickedEl
.
按照惯例,我们将该 变量设为私有。这用于使对象可用于私有方法。这是为在ECMAScript的语言规范的错误导致一种变通方法这个不正确地对内部函数来设定。
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);
这提醒...
用途那认为它叫戴夫
UsesThis 认为它被称为 undefined
这是一种使内部函数(在其他函数中定义的函数)更像它们应该工作的方法。在 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 暗示道格拉斯·克罗克福德(Douglas Crockford)认为这是个好主意一样。
使用的that
是不是真的有必要,如果你与使用的解决办法call()
或apply()
:
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);
};
有时this
可以引用另一个范围并引用其他内容,例如假设您想在 DOM 事件中调用构造函数方法,在这种情况下this
将引用 DOM 元素而不是创建的对象。
HTML
<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
上面的解决方案将this
帮助that
我们可以访问方法中的 name 属性sayHi
from that
,因此可以在 DOM 调用中调用它而不会出现问题。
另一种解决方案是分配一个空that
对象并为其添加属性和方法,然后返回它。但是使用此解决方案,您丢失prototype
了构造函数的 。
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};