【问题标题】:Get function caller scope获取函数调用者范围
【发布时间】:2009-12-26 23:36:19
【问题描述】:

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

我有这个例子:

var myObject = {
    id: 1,
    printId: function() {
        var myId = function() {
            return this.id;
        }
        console.log(myId());
    }
}

myObject.printId(); // prints 'undefined'

上面的示例打印出undefined,因为'this' 似乎是默认情况下新函数内的窗口范围(在本例中为myId)。有什么方法可以在执行之前使用应用正确范围的代理?

类似这样的东西(虚构):

var execute = function( fn ) {
    fn.apply(fn.caller.scope);
}

var myObject = {
    id: 1,
    printId: function() {
        var myId = function() {
            return this.id;
        }
        execute( myId );
    }
}

【问题讨论】:

    标签: javascript scope this


    【解决方案1】:

    如果您使用Prototype library,您可以像这样使用 Function#bind():

    var myObject = {
        id: 1,
        printId: function() {
            var myId = function() {
                return this.id;
            }.bind(this);
            console.log(myId());
        }
    }
    

    也许有点矫枉过正,但如果您广泛使用此类对象,则可能值得查找。

    【讨论】:

    【解决方案2】:

    尝试以下方法:

    var myObject = {
        id: 1,
        printId: function() {
            var myId = function() {
                return this.id;
            }
            console.log(myId.apply(this));
        }
    }
    
    myObject.printId(); // prints '1'
    

    问题是你想在printId的范围内运行函数myId,而不是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 内部。这意味着myId 中的this 指的是printId,而不是myObject。由于printId存储在myObject中,this中的printId指的是myObject,所以myId.apply(this)里面printId改变了myId的包含范围从printId到@98765444因此,myId 中的this 现在指的是myObject。在第二个示例中,myId 立即存储在myObject 中,因此printIdmyId 中的this 指的是同一个对象,即myObject。这有任何意义吗? :P

    【讨论】:

    • 很好的答案,但您可能想在最后删除现在不正确的评论;)。
    • 这并不能解决问题(也许我解释得不够好)。当我已经在正确的范围 (myObject) 中时,为什么还需要 apply()?请参阅我的虚构示例。
    • 我试图在我的回答中解释它。告诉我这是否更清楚。
    【解决方案3】:

    Function.bind() 现在被浏览器很好地支持,正如ECMAScript5 所指定的那样。 (更新原型以匹配 ES5 规范)

    对于那些仍在寻找这篇文章的人。

    【讨论】:

      【解决方案4】:

      有什么问题:

      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()

      【讨论】:

        【解决方案5】:
        var myObject = {
            id: 1,
            printId: function() {
                var _this = this;
                var myId = function() { 
                    return _this.id;
                }
                console.log(myId());
            }
        }
        

        【讨论】:

          【解决方案6】:
          var myObj = (function()
          {
            var id = 1;
            return {
              printId: function(){
               console.log(id);
          
          };
          })();
          
          
          myObj.printId();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-11
            • 1970-01-01
            • 2016-12-11
            • 1970-01-01
            • 2019-09-07
            • 2016-05-08
            相关资源
            最近更新 更多