是否可以提取函数调用范围?
我有这个例子:
var myObject = {
id: 1,
printId: function() {
var myId = function() {
return this.id;
}
console.log(myId());
}
}
myObject.printId(); // prints 'undefined'
上面的示例打印出undefined
,因为在新函数(在本例中为myId)中,'this'似乎是默认的窗口范围。有没有什么办法可以在执行之前使用应用正确范围的代理?
像这样的东西(虚构):
var execute = function( fn ) {
fn.apply(fn.caller.scope);
}
var myObject = {
id: 1,
printId: function() {
var myId = function() {
return this.id;
}
execute( myId );
}
}
答案 0 :(得分:3)
尝试以下方法:
var myObject = {
id: 1,
printId: function() {
var myId = function() {
return this.id;
}
console.log(myId.apply(this));
}
}
myObject.printId(); // prints '1'
问题是您希望在myId
范围内运行函数printId
,而不是myId
的范围。您可以通过将函数置于myObject
内而不是将其置于printId
内来创建函数以使其获得相同的范围:
var myObject = {
id: 1,
printId: function() {
this.myId = function() {
return this.id;
}
console.log(this.myId());
}
}
myObject.printId(); // prints '1'
var
将变量存储在函数范围中,这意味着myId
存储在printId
中。这意味着this
中的myId
引用printId
,而不是myObject
。由于printId
存储在myObject
中,this
中的printId
引用myObject
,myId.apply(this)
内的printId
更改了包含myId
从printId
到myObject
的{{1}}范围,因此this
中的myId
现在指的是myObject
。在第二个示例中,myId
立即存储在myObject
中,this
和printId
中的myId
引用同一个对象,即myObject
}。这有什么意义吗? :P
答案 1 :(得分:3)
如果使用Prototype library,可以使用Function#bind(),如下所示:
var myObject = {
id: 1,
printId: function() {
var myId = function() {
return this.id;
}.bind(this);
console.log(myId());
}
}
或许有点矫枉过正,但是如果你广泛使用这样的物体,可能值得一试。
答案 2 :(得分:2)
Function.bind()
,正如ECMAScript5所指定的那样。 (原型更新以匹配ES5规格)
对于那些仍然找到这篇文章的人。
答案 3 :(得分:1)
出了什么问题:
var myObject = {
id: 1,
printId: function() {
return this.id;
}
}
如果不是那样的话:
var myObject = {
id: 1,
printId: function() {
var myid = function() {
return this.id;
};
return myid.apply(this);
}
}
请参阅apply()
。
答案 4 :(得分:1)
var myObject = {
id: 1,
printId: function() {
var _this = this;
var myId = function() {
return _this.id;
}
console.log(myId());
}
}
答案 5 :(得分:0)
var myObj = (function()
{
var id = 1;
return {
printId: function(){
console.log(id);
};
})();
myObj.printId();