Javascript在对象中动态创建函数
我只是在学习javascript,我遇到了一个与范围界定相关的问题 这是密码Javascript在对象中动态创建函数,javascript,Javascript,我只是在学习javascript,我遇到了一个与范围界定相关的问题 这是密码 函数用户(属性){ 对于(属性中的var i){ (功能(){ 这个['get'+i]=函数(){ 归还财产[i]; }; }) (); } } var me=新用户({ Id:54, 姓名:“ohyou” }); console.log(me.getName()); console.log(me.getId()); 我希望它如何工作:它应该创建属于me对象的两个函数getName和getId 工作原理:它创建了我想
函数用户(属性){
对于(属性中的var i){
(功能(){
这个['get'+i]=函数(){
归还财产[i];
};
}) ();
}
}
var me=新用户({
Id:54,
姓名:“ohyou”
});
console.log(me.getName());
console.log(me.getId());
我希望它如何工作:它应该创建属于me
对象的两个函数getName
和getId
工作原理:它创建了我想要的两个函数,但它们属于窗口
我尝试的是:
- 我尝试删除第3行上的函数。它执行我想要的操作,但是现在它返回两次
“ohyou”,而不是返回name
和id
name
- 我尝试使用
作用域中的函数,与前一个案例一样,问题仍然存在-它返回窗口
两次名称
请注意,使用电话发此帖子,对于可能出现的打字错误或格式问题,我深表歉意。另外,请原谅我的英语技能。试着理解以下代码的工作原理:
函数用户(属性){
对于(属性中的var i){
使用({i:i,self:this,props:properties}){
self[“get”+i]=函数(){
返回道具[i];
};
}
}
}
var me=新用户({
Id:54,
姓名:“ohyou”
});
警报(me.getName());
警报(me.getId())
如果使用Object.keys
然后使用forEach
,则可以避免所有这些闭包和其他事情,这已经引入了一个新的作用域。然后必须传递这个值,这是第二个参数:
function User(properties) {
Object.keys(properties).forEach(function(k) {
this['get'+ k] = function() {
return properties[k]
}
},this)
}
您必须记住一点,任何不属于任何对象的函数都将始终属于窗口对象
例如,如果我们修改对象并添加新方法
me.doSomeWork = function(){
this.myLuckyNumber = 10;
var that = this;
function doubleMyLuckyNumber(){
console.log(this); //window
that.myLuckyNumber = that.myLuckyNumber * 2;
}
doubleMyLuckyNumber();
};
me.doSomeWork();
console.log(me.myLuckyNumber) //outputs 20
因此,始终保存对var的引用,以便在内部方法中使用它。您可以使用其他人建议的任何方法,但我更喜欢詹姆斯·伊曼农的方法。这可能是某个地方重复的方法的重复。最好的解决方案是放弃循环,并使用Object.keys(properties).forEach
,您可以处理这个
,也可以处理那个
。将循环更改为您建议的函数,但显然不起作用。嘿,Aadit-我个人喜欢这里使用“with”,但我读过的文档避开了它-尽管我相信您在这里的用法很好。@jamesemanonwith
语句不错。请看下面的问题:非常感谢。即使只使用{i:i}
,它也能完美工作,但我不明白为什么。我也不明白为什么在我的情况下它不起作用。@哦,我添加了一个解释,解释了为什么你的代码不能按预期工作。哦,现在我明白为什么了。谢谢你的详细回答。虽然这太慢了。首先遍历所有属性以获取密钥名称。然后再次循环它们,每次运行回调函数。没什么好担心的,引擎速度非常快。如果我想要可读的代码和更好的抽象,我会远离for
循环。我想每个人都有自己的风格。我也喜欢写函数代码,但不是用JavaScript。不管怎样,+1。我知道,谢谢你提醒。我只是对我没有传递数据的内部范围感到困惑。
me.doSomeWork = function(){
this.myLuckyNumber = 10;
var that = this;
function doubleMyLuckyNumber(){
console.log(this); //window
that.myLuckyNumber = that.myLuckyNumber * 2;
}
doubleMyLuckyNumber();
};
me.doSomeWork();
console.log(me.myLuckyNumber) //outputs 20