我有一个与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
我通常使用第二种方法,但我只是想完全理解它的区别以及它为何起作用:-)。 绝对明白,它只适用于单实例场景。
答案 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
。