对象初始值设定项此实例名称

时间:2013-10-16 05:40:29

标签: javascript

我有一个与JavaScript对象初始化符号相关的问题。我对顶级示例的工作有点惊讶,因为它引用了定义中实例的名称。这两种方法是否相同?我通常使用第二种方法,但它们似乎也达到了同样的效果。

var myObj = 
{
   Message:"Test",
   someMethod:function(){
      $.get("/someUrl",function(){
        myObj.Message = "Returned Value";
      })
   }
}

var myObj = 
{
   Message:"Test",
   someMethod:function(){
      var that = this; //have to capture this in order to use it in a different context.
      $.get("/someUrl",function(){
        that.Message = "Returned Value";
      })
   }
}

我认为顶级方法具有优势,因为您不必跟踪this的当前含义,因为它可能会在不同的上下文中发生变化。还有其他差异吗?

编辑: 了解顶级方法并不总是推荐的方法,但我想在某些情况下我仍然会看到一些优势。其中一个例子是KnockoutJS,其中绑定解析将重新定义视图模型上绑定的点击处理程序中this的含义。更多信息: http://www.appliness.com/10-things-to-know-about-knockout-js-on-day-one/

在这种情况下,我必须手动对this

的当前含义进行一些记录

我通常使用第二种方法,但我只是想完全理解它的区别以及它为何起作用:-)。 绝对明白,它只适用于单实例场景。

2 个答案:

答案 0 :(得分:1)

this由JS解释器根据调用内容的方式设置。当你有一个对象类型的多个实例时,它是非常有用的(并且基本上是必需的)因为this是唯一知道要引用哪个对象所以建议你使用第二个代码示例。

obj.method()之类的任何对象方法调用都会导致this在方法中自动设置为obj

如果您有一个单例(只有一个对象的实例),那么您当然可以使用命名变量,但通常不需要使用该名称,因为this将正常工作您可以正确编写对象方法的访问权限。

答案 1 :(得分:1)

JavaScript的闭包语义在这里有点有趣。事实上,它们将捕获当前分配给的变量,尽管逻辑可能表明该变量尚不存在。

这实际上是JavaScript variable hoisting的结果。在可以分配变量之前,必须声明它。因此,即使在myObj不在全局范围内的情况下,它仍将被该函数捕获,因为有效地,您正在写这个:

var o = (function () {
    var myObj; // hoisted declaration
    myObj = {
        message: "test",
        someMethod: function () { alert(myObj.message); },
    };
    return myObj;
})();
o.someMethod(); // alerts 'test'

但是,这并不总是有效。如果你可以强制将变量赋值给闭包的范围,那么变量确实是未定义的。

function createObj() {
    return {
        message: "test",
        someMethod: function () { alert(myObj.message); },
    };
}

var o = (function () {
    var myObj;
    myObj = createObj();
    return myObj;
})();
o.someMethod(); // error: myObj is not defined

因此,虽然使用该名称有时可能会起作用,但这是一种更脆弱的方法。如果未捕获名称,或者内部重用变量名称,则可能完全中断。使用名称而不是使用this会导致代码在重构时中断,即使只是简单地移动代码,如果您没有意识到问题的来源,这可能会很难调试。

基本上,虽然第一种方法有时可能有效,但它不是一般解决方案,并且与使用this相比没有任何优势,因此最好使用this