Javascript:使用对象字面量自身键函数中的引用而不是'this'

16

在函数内部引用对象字面量是否有问题?这似乎完全没有问题,但我想确保没有其他影响。

以下是我所说的示例:

不使用:

var obj = {
    key1: "it",
    key2: function(){return this.key1 + " works!"}
};
alert(obj.key2());

使用:

var obj = {
    key1: "it",
    key2: function(){return obj.key1 + " works!"}
};
alert(obj.key2());
5个回答

21

两者都可能存在问题。

var obj = {
    key1: "it",
    key2: function(){ return this.key1 + " works!" }
};
var func = obj.key2;
alert(func()); // error

func不是作为obj的一个方法被调用时,this可能会引用其他内容(在这里是全局对象"window")。

var obj = {
    key1: "it",
    key2: function(){ return obj.key1 + " works!" }
};
var newref = obj;
obj = { key1: "something else"; };
alert(newref.key2()); // "something else works"

在这里,我们从另一个引用中访问对象,尽管函数中的obj现在可能指向其他对象。

因此,您将不得不选择哪种情况更有可能。如果您真的想使其安全,请防止交换obj

// ES6 - use `const`:
const obj = {
    key1: "it",
    key2: function(){ return obj.key1 + " works always!" }
};

// ES5: use a closure where the `obj` is stored in a local-scoped variable:
var obj = (function(){
    var local = {
        key1: "it",
        key2: function(){ return local.key1 + " works always!" }
    };
    return local;
})();

或者你可以将该函数bind()到对象上:

var obj = {
    key1: "it",
    key2: function(){ return this.key1 + " works always!" }
}
obj.key2 = obj.key2.bind(obj);

1

变量作用域绑定会有所不同。如果您稍后修改 obj,则会修改 key2 的返回值:

var newobj = obj;
obj = { key1: "new" };
alert(newobj.key2());

现在它会提示“新的作品!”,因为即使您在原始对象(现在是newobj)上调用key2(),对obj.key1的引用现在也绑定到新obj实例的值。使用this可以防止这种情况发生。
演示:http://jsfiddle.net/m6CU3/

1

这些技术中的任何一种或两种都可能适用,具体取决于情况。

函数内的this值取决于函数的调用方式。如果您将函数作为对象的属性进行调用,例如:

obj.key2();
//or
obj["key2"]();

那么this将成为那个对象。无论该对象是通过对象字面量还是其他方式创建的都不重要。

但是您可以使用{{link1:.call()}}或.apply()调用函数并显式地将this设置为其他对象。

还要考虑:

var obj = {
    key1: "it",
    key2: function(){return this.key1 + " works!"}
};
alert(obj.key2()); // alerts "it works!"

var func = obj.key2;
alert(func())​;     // alerts "undefined works!"

我正在设置func引用与obj.key2相同的函数,但调用它作为func()并不会将this设置为obj

欲了解更多信息,请查看MDN关于this的说明


1
如果您没有使用原型对象,您可以这样做。因为您的对象的所有实例都将返回obj实例的值...

0

我认为脑海中没有任何影响。只是确保你在任何时候都不会意外地这样做:

var obj = {
    key1: "it",
    key2: key1 + " works!"
}

因为那会导致错误。除此之外,你应该可以顺利进行!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接