匿名函数中的“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 使用了正确的缩进。 这似乎不对。在匿名函数内部,this
是 window
。
书上好像有错误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”?的主要内容,如果未能解决你的问题,请参考以下文章