Understanding Javascript scope with "var that = this&qu

Understanding Javascript scope with "var that = this"

本文关键字:that this qu var quot Javascript scope with Understanding      更新时间:2023-09-26

假设我在对象中有以下属性方法:

  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将是调用对象
  • 如果使用callapply调用函数,则会将this指定为callapply的第一个参数
  • 如果它被调用为事件监听器(就像这里一样),this将是事件的目标元素
  • 如果用new调用它作为构造函数,this将是一个新创建的对象,其原型设置为构造函数的prototype属性
  • 如果函数是bind操作的结果,则该函数将始终将this设置为生成它的bind调用的第一个参数。(这是"函数没有固定的this"规则的唯一例外——bind生成的函数实际上有一个不可变的this。)

使用var that = this;是在函数定义时间存储this值的一种方式(而不是函数executiontime,此时this可以是任何值,具体取决于函数的调用方式)。这里的解决方案是将this的外部值存储在变量(传统上称为thatself)中,该变量包含在新定义的函数的范围内,因为新定义的功能可以访问在其外部范围内定义的变量。

因为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/applybind:

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关键字的更多信息。

当从DOM事件调用类的方法时,this引用不起作用。例如,当对象的方法用作onclick的事件处理程序时,this指针指向事件发生的DOM节点。因此,您必须在对象中创建this的专用备份。

this是javascript中的一个关键字,而不是每个函数中定义的默认变量,因此,正如Gareth所说,this将指调用函数的上下文,如果没有上下文,则指全局对象。