Javascript在对象中动态创建函数

时间:2014-10-10 06:19:34

标签: javascript

我正在研究javascript,我遇到了与范围有关的问题。

这是代码

function User (properties) {
    for (var i in properties) {
        (function ()  {
            this ['get' + i] = function () {
                return properties [i];
            };
        }) ();
    }
}

var me = new User ({
    Id : 54,
    Name : 'ohyou'
});

console.log (me.getName ());
console.log (me.getId ());

我希望它如何工作:它应该创建属于getName对象的两个函数getIdme

工作原理:它可以按照我的意愿创建两个函数,但它们属于window

我尝试了什么:

  • 我尝试删除第3行的功能。它可以实现我想要的功能,但现在它返回name" ohyou"两次,而不是返回idname

  • 我尝试使用window范围内的功能,问题与前一种情况一样持续存在 - 它会两次返回name

问题:我做错了什么,如何让它按我的意愿运作?

P.S。使用手机发布此帖子,抱歉可能存在拼写错误或格式问题。另外,请原谅我的英语技能。

4 个答案:

答案 0 :(得分:2)

尝试理解以下代码的工作原理:



function User(properties) {
    for (var i in properties) {
        with ({ i: i, self: this, props: properties }) {
            self["get" + i] = function () {
                return props[i];
            };
        }
    }
}

var me = new User({
    Id: 54,
    Name: "ohyou"
});

alert(me.getName());
alert(me.getId());




这是with声明的合法用法之一。

我发现with语句比使用其他人建议的立即调用的函数表达式(IIFE)更简洁。

修改:如果您正确使用,with关键字也不错。有一些合法用途:

http://webreflection.blogspot.in/2009/12/with-worlds-most-misunderstood.html


您的代码无法正常工作的原因是因为每个函数都拥有自己的this值。因此,当您在for循环中立即调用函数表达式时,函数内的this值不再是您的新对象。它是window。要解决这个问题,您可以执行以下操作:

(function (i, self, props) {
    self["get" + i] = function () {
        return props[i];
    };
}(i, this, properties))

但是使用with语句干净且速度更快。它更快,因为你没有调用函数。

答案 1 :(得分:2)

function User (properties) {
    var that = this;
    for (var i in properties) {
        (function (i)  {

            that ['get' + i] = function () {
                return properties [i];
            };

        }) (i);
    }
}

var me = new User ({
    Id : 54,
    Name : 'ohyou'
});

答案 2 :(得分:2)

如果您使用Object.keys然后forEach已经引入了新范围,则可以避免所有这些闭包和其他内容。然后,您必须传递this值,这是第二个参数:

function User(properties) {
  Object.keys(properties).forEach(function(k) {
    this['get'+ k] = function() {
      return properties[k]
    }
  },this)
}

答案 3 :(得分:0)

您必须记住的一件事是,任何不属于任何对象的函数都将永远属于窗口对象

例如,如果我们修改您的对象并添加新方法,

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 以在内部方法中使用它。您可以使用其他人建议的任何方式,但我更喜欢James emanon的方法。