在一个JavaScript文件中,我看到了: javascript
function Somefunction(){ var that = this; ... }
什么是声明的目的that
和分配this
本呢? css
这是使内部功能(在其余功能内定义的功能)更按需工做的一种技巧。 在JavaScript中,当你定义里面另一个功能, this
将自动被设置为全局范围。 这可能会形成混淆,由于您但愿this
具备与外部函数相同的值。 html
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
中的car.start
),而后在该方法内部建立函数(例如activateStarter
)时,这尤为是一个问题。 在顶层方法中, this
指向对象,它是的方法(在本例中为car
),可是在内部函数中, this
如今指向全局范围。 真痛苦 java
建立一个变量以按惯例在两个范围内使用都是解决javascript这个很是广泛的问题的方法(尽管它在jquery函数中也颇有用)。 这就是为何很通常名曰that
被使用。 这是克服语言缺陷的一种容易识别的约定。 jquery
就像El Ronnoco在道格拉斯 ·克罗克福德( Douglas Crockford)暗示的那样,这是一个好主意。 app
有时, this
能够参考另外一个范围,是指别的东西,例如,假设你要调用一个DOM事件中构造函数方法,在这种状况下, this
将涉及到的DOM元素而不是建立的对象。 ide
的HTML 函数
<button id="button">Alert Name</button>
JS flex
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
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; };
若是您经过使用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); };
这是一个例子
$(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元素。
从克罗福德
按照惯例,咱们作一个私有变量 。 这用于使对象可用于私有方法。 这是为在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)
用途这被认为是未定义的