Understanding Javascript scope with "var that = this&qu
Understanding Javascript scope with "var that = this"
假设我在对象中有以下属性方法:
onReady: function FlashUpload_onReady()
{
Alfresco.util.Ajax.jsonGet({
url: Alfresco.constants.PROXY_URI + "org/app/classification",
successCallback: {
fn: function (o) {
var classButtonMenu = [],
menuLabel, that = this;
var selectButtonClick = function (p_sType, p_aArgs, p_oItem) {
var sText = p_oItem.cfg.getProperty("text");
that.classificationSelectButton.set("label", sText);
};
for (var i in o.json.items) {
classButtonMenu.push({
text: o.json.items[i].classification,
value: o.json.items[i].filename,
onClick: {fn: selectButtonClick}
});
}
this.classificationSelectButton = new YAHOO.widget.Button({
id: this.id + "-appClassification",
type: "menu",
label: classButtonMenu[0].text,
name: "appClassification",
menu: classButtonMenu,
container: this.id + "-appClassificationSection-div"
});
},
scope: this
},
failureMessage: "Failed to retrieve classifications!"
});
我花了一些猜测工作才弄清楚,在selectButtonClick
函数中,我需要引用that
而不是this
才能访问this.classificationSelectButton
(否则会出现undefined
),但我不确定为什么我不能使用this
。我的最佳猜测是,一旦调用构造函数,在new YAHOO.widget.Button
中引用的整个对象中的任何属性都会以某种方式失去作用域。
有人能解释一下为什么我必须用var that = this
引用classificationSelectButton
,而不仅仅是调用"this.classificationSelectButton"吗?
最重要的是要理解的是,函数对象没有固定的this
值——this
的值根据函数的调用方式而变化。我们说函数是用某个特定的this
值来调用的——this
值是在调用时确定的,而不是在定义时确定的。
- 如果函数被调用为"原始"函数(例如,只执行
someFunc()
),则this
将是全局对象(浏览器中的window
)(如果函数在严格模式下运行,则为undefined
) - 如果它作为对象上的方法被调用,
this
将是调用对象 - 如果使用
call
或apply
调用函数,则会将this
指定为call
或apply
的第一个参数 - 如果它被调用为事件监听器(就像这里一样),
this
将是事件的目标元素 - 如果用
new
调用它作为构造函数,this
将是一个新创建的对象,其原型设置为构造函数的prototype
属性 - 如果函数是
bind
操作的结果,则该函数将始终将this
设置为生成它的bind
调用的第一个参数。(这是"函数没有固定的this
"规则的唯一例外——bind
生成的函数实际上有一个不可变的this
。)
使用var that = this;
是在函数定义时间存储this
值的一种方式(而不是函数executiontime,此时this
可以是任何值,具体取决于函数的调用方式)。这里的解决方案是将this
的外部值存储在变量(传统上称为that
或self
)中,该变量包含在新定义的函数的范围内,因为新定义的功能可以访问在其外部范围内定义的变量。
因为this
会根据其运行的上下文更改其值。
在selectButtonClick
函数中,this
将引用该函数的上下文,而不是外部上下文。因此,您需要在外部上下文中为this
指定一个不同的名称,selectButtonClick
函数内部可以引用该名称。
有词法作用域:函数中声明的变量和传递给函数的参数仅在函数内部(以及函数内部)可见。
var x = 1; // `1` is now known as `x`
var that = this; // the current meaning of `this` is captured in `that`
词汇范围的规则是非常直观的。显式分配变量。
然后是动态范围:this
。这是一个神奇的东西,它会根据你如何调用函数来改变它的含义。它也被称为上下文。有几种方法可以赋予它意义
考虑一个函数:
function print() { console.log(this); }
首先,严格模式下的默认上下文为undefined
,正常模式下的全局对象为
print(); // Window
其次,您可以将其作为一个方法,并通过引用一个对象来调用它,然后引用一个点,然后引用函数:
var obj = {};
obj.printMethod = print;
obj.printMethod(); // Object
请注意,如果您调用不带句点的方法,上下文将回退到默认值:
var printMethod = obj.printMethod;
printMethod(); // Window
最后,有一种分配上下文的方法是使用call
/apply
或bind
:
print.call(obj, 1, 2); // Object
print.apply(obj, [ 1, 2 ]); // Object
var boundPrint = print.bind(obj);
boundPrint(); // Object
为了更好地理解上下文,您可能想尝试使用这样的简单示例。John Resig有非常好的JavaScript上下文交互式幻灯片,您可以在这里学习和测试自己。
将其存储在变量中可以在this
可能引用其他内容的其他范围中访问它。
请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this,http://www.quirksmode.org/js/this.htmlJavaScript中变量的范围是什么?有关CCD_ 51关键字的更多信息。
this
引用不起作用。例如,当对象的方法用作onclick的事件处理程序时,this
指针指向事件发生的DOM节点。因此,您必须在对象中创建this
的专用备份。
this是javascript中的一个关键字,而不是每个函数中定义的默认变量,因此,正如Gareth所说,this将指调用函数的上下文,如果没有上下文,则指全局对象。
- $(this).prop('property') vs. this.property
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- 在另一个函数中使用变量this
- this.router在AngularJS 2中未定义
- reactjs this.refs vs document.getElementById
- JavaScript 中的嵌套函数和 “this” 关键字
- React+Meteor:this.ops返回未定义
- Understanding Javascript scope with "var that = this&qu
- 在函数中获取正确的作用域(不使用that=this)
- Javascript scope and self=this, _this=this, that=this
- Javascript methods: this & that
- Javascript: split by this|that
- 在javascript正则表达式中检查“this AND that WITHOUT this”的方法
- 声明var that = this的原因是什么?在javascript
- JS和OOP:滥用“that = this”模式
- 将this/self/that绑定到事件回调,当它可以不作为事件回调调用时
- 选择$this,显示$that -如何在表单中做到这一点
- that = $(this)表示setTimeout闭包没有按预期工作
- 试图使用“this”;而不必使用“that”将函数作为参数传递给jquery委托事件处理程序
- 使用“;这个“;或“;“;(其中var that=this)