【问题标题】:"this" inside an anonymous function?匿名函数中的“this”?
【发布时间】:2012-03-22 01:21:01
【问题描述】:

在 John Resig 的“Pro Javascript 技术”一书中,他描述了一种使用以下代码生成动态对象方法的方法:

// Create a new user object that accepts an object of properties
function User(properties) {
    // Iterate through the properties of the object, and make sure
    // that it's properly scoped (as discussed previously)
    for (var i in properties) {
        (function() {
            // Create a new getter for the property
            this["get" + i] = function() {
                return properties[i];
            };
            // Create a new setter for the property
            this["set" + i] = function(val) {
                properties[i] = val;
            };
        })();
    }
}

问题是当我尝试实例化上述对象时,动态方法被附加到窗口对象而不是实例化对象。似乎“this”指的是窗口。

// Create a new user object instance and pass in an object of
// properties to seed it with
var user = new User({
name: "Bob",
age: 44
});

alert( user.getname() );

运行上面的代码会抛出这个错误“user.getname is not a function”。

为每个实例化的对象生成动态函数的正确方法是什么?

【问题讨论】:

  • 我确信 John Resig 使用了正确的缩进。
  • 这似乎不对。在匿名函数内部,thiswindow
  • @Rocket:你怎么没看到那里的压痕?
  • 在非数字属性枚举中使用 i 作为键名让我很恼火。

标签: javascript anonymous-function


【解决方案1】:

这是书中的代码吗?我有这本书,但我还没读完。

这是书中的一个错误。查看勘误表:http://www.apress.com/9781590597279

在匿名函数内部,this 是全局的window

您可以在其后添加.call(this, i) 使其工作。

function User(properties) {
    // Iterate through the properties of the object, and make sure
    // that it's properly scoped (as discussed previously)
    for (var i in properties) {
        (function(i) {
            // Create a new getter for the property
            this["get" + i] = function() {
                return properties[i];
            };
            // Create a new setter for the property
            this["set" + i] = function(val) {
                properties[i] = val;
            };
        }).call(this, i);
    }
} 

【讨论】:

  • 我有这本书,但我还没读过。 那么你用它做了什么?书店?木纤维的来源?壁纸?
  • @JaredFarrish:它被用来保持我书架上的书对称。不,但说真的,我只需要一些时间来真正阅读它:-P
  • 这本书来自books.google.com/…
  • 咀嚼完后把它传下去。 ;O
  • val 参数传递给 anon 函数的目的是什么?好像没有被使用...
【解决方案2】:

内部自执行函数中的this与外部User函数中的this不同。如您所见,它指的是全局window

如果您通过添加一个引用外部this 的变量来稍微修改代码,问题就得到了解决。

function User(properties) {
  var self = this;
  for (var i in properties) { 
    (function() { 
      self["get" + i] = function() { /* ... */ }; 
      self["set" + i] = function() { /* ... */ }; 
    })();
  }
}

也就是说,我不确定为什么这里甚至需要匿名自执行功能,所以您可以选择完全省略它,就像这样:

function User(properties) {
  for (var i in properties) { 
      this["get" + i] = function() { /* ... */ }; 
      this["set" + i] = function() { /* ... */ }; 
  }
}

【讨论】:

    【解决方案3】:

    这里是如何做到这一点。您需要将上下文保存到另一个变量中。另一种选择是不执行您在 for 循环中执行的此内部函数。

    // Create a new user object that accepts an object of properties
    function User( properties ) {
       // Iterate through the properties of the object, and make sure
       // that it's properly scoped (as discussed previously)
       var that = this;
       for ( var i in properties ) { (function(){
           // Create a new getter for the property
           that[ "get" + i ] = function() {
              return properties[i];
           };
           // Create a new setter for the property
           that[ "set" + i ] = function(val) {
               properties[i] = val;
           };
        })(); }
    }
    

    选项 2:

    // Create a new user object that accepts an object of properties
    function User( properties ) {
       // Iterate through the properties of the object, and make sure
       // that it's properly scoped (as discussed previously)
       for ( var i in properties ) {
           // Create a new getter for the property
           this[ "get" + i ] = function() {
              return properties[i];
           };
           // Create a new setter for the property
           this[ "set" + i ] = function(val) {
               properties[i] = val;
           };
        }
    }
    

    【讨论】:

    • 这两个选项都不起作用,因为它们使用捕获的i 版本,该版本随着循环的执行而变化,并将i 作为最后一个属性名称。约翰的部分例子是如何避免这个问题。但是,通过将i 作为参数传递,可以轻松修复选项 1。要修复选项 2,您可以将其变成选项 1 的固定版本。
    【解决方案4】:

    您始终可以使用apply 方法为任何函数调用强制另一个this

    (function() {
        // Create a new getter for the property
        this["get" + i] = function() {
            return properties[i];
        };
        // Create a new setter for the property
        this["set" + i] = function(val) {
            properties[i] = val;
        };
    }).apply(this);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-08
      • 2012-05-10
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      相关资源
      最近更新 更多