【问题标题】:How to augment an object with custom method in javascript?如何在 javascript 中使用自定义方法扩充对象?
【发布时间】:2013-04-08 03:33:35
【问题描述】:

我想知道在 javascript (nodejs) 中如何为从外部(数据库、网络等)接收的对象提供行为是否有一些最佳实践。

例如,假设我有一些 getById(<Id>) 函数从数据库中获取正确的对象,你将如何在此函数返回的对象上添加 savemethod?

这是我想要的:

var getById = function (id) {
   var obj = callSomeExternalCode(id);
   return obj;
};
var myObj = getById('1234');
myObj.aProperty = 'a_new_value';
myObj.save();

我宁愿避免使用伪经典的解决方案(无论如何,如果你能提供一个好的解决方案,我可能会根据我的风格调整它)

编辑:我忘了提,将这些方法定义在一个单独的“父”对象中会非常好(即使我认为原型继承不是答案)

谢谢

【问题讨论】:

    标签: javascript factory


    【解决方案1】:

    将这些方法定义在单独的“父”对象中会非常好

    那就这样做吧:

    var parent = {
        save: function() {…}
    };
    function getById(id) {
        // There's a shortcut function called "extend" for this in many libs:
        // return extend(callSomeExternalCode(id), parent);
        // which does
        var obj = callSomeExternalCode(id);
        for (var p in parent)
            obj[p] = parent[p]; // copy
        return obj;
    }
    

    我想,原始继承不是答案

    可能是这样,特别是如果 parent 上的属性比新 obj 上的属性多。然后你可以这样做(即使没有任何伪经典代码):

    function getById(id) {
        // return extend(Object.create(parent), callSomeExternalCode(id));
        // long:
        var obj = callSomeExternalCode(id),
            res = Object.create(parent);
        for (var p in obj)
            res[p] = obj[p]; // copy
        return res;
    }
    

    【讨论】:

    • 我知道这可能看起来很“脏”,但正如 here 所述,可以在 v8 中交换“原型”对象......对你来说它看起来太脏了吗?
    • 是的,我认为non-standard __proto__ property 很脏——它在 IE 中也不起作用。当然Object.setPrototypeOf 有时可能很方便,但我担心没有标准化的方法......
    • 哦,这不是问题,这是一个仅限节点的项目 :) 无论如何,我同意...只要它不是完全标准化的,我就觉得不舒服 :D
    【解决方案2】:

    为什么不将 myObj 传递给前面的另一个工厂/装饰对象?

    myAugmentedObj = User.augment(myObj);
    myAugmentedObj.save();
    

    编辑:

    更具体地说:

    var UserModule = {
      save: function ( ... ) { ... },
      anotherFunction: function ( ... ) { ... }
    };
    
    var User = {
      augment: function (user) {
        return $.extend(user, UserModule);
      }
    };
    

    顺便说一句,

    我实际上会让 User 成为一个类,并将 UserModule 作为它的一部分而不是一个单独的对象,然后创建新对象作为 User 的实例。但是您明确提到要避免经典继承。

    【讨论】:

    • 是的,这就是我的想法。问题是如何实现 User.Augment 函数本身(我的意思是,从模板复制?其他一些技术?)
    【解决方案3】:

    这样的?

    var getById = function (id) {
        var obj = callSomeExternalCode(id);
    
        obj.save = function() {
            // do something
        }
    
        return obj;
    };
    

    【讨论】:

    • 我编辑了这个问题来解释为什么我更喜欢避免这个解决方案:)(无论如何,这不是为每个对象复制保存功能吗?)
    • 是的,它正在创建几个save函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 2016-08-08
    相关资源
    最近更新 更多