匿名函数中的“this”?

Posted

技术标签:

【中文标题】匿名函数中的“this”?【英文标题】:"this" inside an anonymous function? 【发布时间】: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 书上好像有错误arrixlive.wordpress.com/2007/01/09/… @Rocket:你怎么没看到那里的压痕? 在非数字属性枚举中使用 i 作为键名让我很恼火。 【参考方案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);

【讨论】:

以上是关于匿名函数中的“this”?的主要内容,如果未能解决你的问题,请参考以下文章

Vue中匿名函数和箭头函数的this

闭包和匿名函数

272 函数的理解和使用:回调函数,匿名函数自调用IIFE,**函数中的this**

js--call箭头函数/匿名函数

JavaScript中匿名函数this指向问题

如何在匿名函数中访问“this”? [复制]