【问题标题】:Affecting Object's Properties Inside Callbacks in Node.js在 Node.js 的回调中影响对象的属性
【发布时间】:2011-12-26 11:32:22
【问题描述】:

我正在用 Node.js 编写一个简单的原型,其中包含一些我可能在使用该原型的对象中需要的辅助方法。我想要的一种方法是 jQuery 的.each() 的实现。我在他们的开发版本中查看了 jQuery 的实现,并尝试在我的简化版本中模拟它。

// Loop through the object using a callback
BaseProto.prototype.each = function (cb, args) {
    var obj = this.get(),   // Get our object as a plain object
        prop;

    /** Code to make sure the the args passed are actually an array **/

    if (typeof cb === "function") {
        // For each property in our object
        for (prop in obj) {
            // Apply the callback to the object's property and pass
            // the index, the property, and whatever else as arguments
            if (cb.apply(obj[prop], [ prop, obj[prop] ].concat(args)) === false) {
                // Get out if the function returns false
                break;
            }
        }
    }

    // Reset our object with the new one
    return this.reset(obj);
};

问题在于,虽然回调肯定会被触发,但它对对象的属性没有任何影响。无论我在回调中做什么,更改都保留在回调的范围内。

这是一个我一直在测试的简单回调示例。

var BaseProtoTestObj = new BaseProto();

/** Set some properties to BaseProtoTestObj **/

function cb1 ( key, val ) {
    var prop;

    key = key.toString() + " Callbacked";
    val = val.toString() + " Callbacked";

    for (prop in this) {
        this[prop] = this[prop].toString() + " Callbacked";
    }
}

// Doesn't have any effect on BaseProtoTestObj
BaseProtoTestObj.each(cb1);

我可以看到 jQuery 的 .each() 中还有很多事情要做,但据我所知,它是为了优化以及迭代数组和对象的能力。

最后,我的问题很简单。 jQuery 正在做什么来影响属性,我不在我的.each() 中?


编辑

我想另一个问题是我的逻辑是否根本上是错误的,而您不能以这种方式修改对象的属性。

【问题讨论】:

  • 可以看到jQuery的.each()here。它在第 610 行。

标签: javascript node.js iteration


【解决方案1】:

您不需要自定义方法:

for(var prop in object) {
   var value = object[prop];
   // do something with value and/or prop
}

虽然如果你真的需要.each(),你可以这样做:

Object.prototype.each = function(cb) {
    for(var propName in this) {
        cb(propName, this[propName]);
    }
}

var foo = { prop: 'value', prop2: 'value2' };
foo.each(function(key,value) {
    // do something here
});    

由于您需要修改属性的实际值,请尝试以下操作:

Object.prototype.mutate = function(cb) {
    for(var propName in this) {
        this[propName] = cb(propName, this[propName]);
    }
}

var obj = {
    a: 'foo',
    b: 'bar',
    c: 'baz'
};

obj.mutate(function(propName, propValue) {
    return propName + '-' + propValue;
});

/*
obj will now be:

var obj = {
    a: 'a-foo',
    b: 'b-bar',
    c: 'c-baz'
};
*/

【讨论】:

  • 在很多情况下,我可能不需要自定义方法,但在某些情况下,最好对对象的每个属性应用回调。假设我正在为我的对象的每个属性将一些东西保存到 redis 数据库中。由于 Node.js 的 redis 库是非阻塞的,我必须为每次保存传递一个回调。在使用 javascript 等时,在循环中创建函数也不是一个好习惯。
  • 您的示例与我正在尝试做的非常相似,但正如您所看到的 here 它与我在问题中描述的问题相同。您实际上无法从回调内部修改任何属性。
  • 这几天我在业余时间一直在思考这个问题,我想到了归还我想要设置的属性的想法。无论出于何种原因,它都感觉像是在作弊。为了保证mutate() 的安全,我必须确保回调返回了一些东西,否则我的所有属性都将是未定义的。我不知道是否有更好的选择。我会接受答案,但如果我能阅读更多人的意见,我会很高兴。谢谢!
  • 这是真的。但是,在我看来,这是最灵活的方式,因为实际上没有办法向 mutate 函数表明您没有更改值。有时您想将值更改为falsenull
猜你喜欢
  • 2018-02-06
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 2022-01-23
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
相关资源
最近更新 更多