获取函数调用范围

时间:2009-12-26 23:36:19

标签: javascript scope this

是否可以提取函数调用范围?

我有这个例子:

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 );
    }
}

6 个答案:

答案 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引用myObjectmyId.apply(this)内的printId更改了包含myIdprintIdmyObject的{​​{1}}范围,因此this中的myId现在指的是myObject。在第二个示例中,myId立即存储在myObject中,thisprintId中的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();