在一个JavaScript文件中,我看到了:
function Somefunction(){
var that = this;
...
}
声明that
并分配this
给它的目的是什么?
在一个JavaScript文件中,我看到了:
function Somefunction(){
var that = this;
...
}
声明that
并分配this
给它的目的是什么?
Answers:
我将以一个插图开始这个答案:
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
as作为别名。它所指的内容很少是明显的,特别是如果函数长于几行。我总是使用更具描述性的别名。在上面的示例中,我可能会使用clickedEl
。
var self = this;
。这个词that
似乎暗示变量是任何东西this
。
forEach
函数带有第二个可选参数,它是函数的绑定。colours.forEach(function(){/* 'this' is bound correctly --> */}, this);
因此,一个音符应该说,var that = this
是不是真正需要用forEach
。
从克罗福德
按照惯例,我们做一个私有的是 可变的。这用于使对象可用于私有方法。这是为在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);
这会提醒...
认为那叫戴夫(Dave)
用途这被认为是未定义的
that
在他的例子中根本没有使用变量。它看起来好像只是创建一个变量保存this
对其余的代码有作用。
这是使内部功能(在其他功能内定义的功能)更按需工作的一种技巧。在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)暗示的那样,这是一个好主意。
有时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
上面会assing的解决方案this
来that
,然后我们就可以和访问里面的name属性sayHi
的方法that
,所以这可以被称为无DOM调用中的问题。
另一个解决方案是分配一个空that
对象并向其添加属性和方法,然后将其返回。但是使用此解决方案,您就失去prototype
了构造函数的。
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};
这是一个例子
$(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();
}
});
}
});
});`
因此,您可以看到此值是两个不同的值,具体取决于您定位的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();
}
});
}
});
});`
..... $(that).css(“ background-color”,“#ffe700”); //这里“ that”的值是“ .our-work-group> p> a”,因为var that = this; 因此,即使我们位于“ this” ='.our-work-single-page',我们仍然可以使用“ that”来操作先前的DOM元素。