假设我在对象中有以下属性方法:
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
内引用的任何属性都会以某种方式失去范围。
有人可以解释为什么我必须使用classificationSelectButton
引用var that = this
而不是仅仅调用`this.classificationSelectButton'吗?
答案 0 :(得分:67)
最重要的是要理解一个函数对象没有固定的this
值 - this
的值会根据函数的调用方式而改变。我们说一个函数是用一些特定的this
值调用的 - this
值是在调用时确定的,而不是定义时间。
someFunc()
),this
将成为全局对象(浏览器中的window
)(或{{ 1}}如果函数在严格模式下运行。)undefined
将成为调用对象。call
或apply
来调用某个功能,this
被指定为this
或call
的第一个参数。apply
将是该事件的目标元素。this
的构造函数调用,new
将是一个新创建的对象,其原型设置为构造函数的this
属性。bind
操作的结果,则该函数将始终永久地将prototype
设置为生成它的this
调用的第一个参数。 (这是“函数没有固定bind
”规则的唯一例外 - this
实际做生成的函数具有不可变bind
。)使用this
是一种在{em>定义时间存储var that = this;
值的方法(而不是函数执行时间,当{{1}时可以是任何东西,取决于调用函数的方式)。这里的解决方案是将this
的外部值存储在一个变量(传统上称为this
或this
)中,该变量包含在新定义的函数的范围内,因为新定义的函数可以访问在其外部范围内定义的变量。
答案 1 :(得分:5)
因为this
会根据其运行的上下文更改其值。
在selectButtonClick
函数中,this
将引用该函数的上下文,而不是外部上下文。所以你需要在外部上下文中给this
一个不同的名称,它可以在selectButtonClick
函数中引用。
答案 2 :(得分:3)
有词法范围:在函数中声明的变量和传递给函数的参数只在函数内部(以及在其内部函数中)可见。
var x = 1; // `1` is now known as `x`
var that = this; // the current meaning of `this` is captured in `that`
词汇范围的规则非常直观。您可以明确指定变量。
然后是动态范围:this
。这是一个神奇的事情,根据你如何调用一个函数来改变它的含义。它也被称为 context 。有几种方法可以赋予它意义。
考虑一个函数:
function print() { console.log(this); }
首先,strict mode中的默认上下文为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中有very nice interactive slides上下文,您可以在其中学习和测试自己。
答案 3 :(得分:1)
将其存储在变量中可让您在this
可能引用其他内容的其他范围内访问它。
有关this
关键字的详情,请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this,http://www.quirksmode.org/js/this.html和What is the scope of variables in JavaScript?。
答案 4 :(得分:1)
从DOM事件调用类的方法时,this
引用不起作用。例如,当对象的方法用作onclick的事件处理程序时,this
指针指向发生事件的DOM节点。因此,您必须在对象中创建this
的私有备份。
答案 5 :(得分:1)
这个是javascript中的关键字,而不是每个函数中定义的默认变量,因此,正如Gareth所说,这个将引用函数所在的上下文调用,如果没有上下文,则调整全局对象。