【问题标题】:How can I extend properly a JS object?如何正确扩展 JS 对象?
【发布时间】:2011-08-23 22:36:29
【问题描述】:

假设我在一个名为 main.js 的文件中有类似的内容:

function obj_name() {}

obj_name.prototype = {
    foo  : function() { alert('hi!'); },
    foo2 : function() { alert('hi again!'); }
}

现在我正在尝试这种方式来扩展另一个文件中的对象extend.js

obj_name.prototype = {
    newfoo : function() { alert('hi #3'); }
}

...但问题是,如果我这样编码,它就可以工作:

obj_name.prototype.newfoo = function() { alert('hi #3'); }

我想这可能是一个菜鸟问题。我什至不知道这是否是扩展对象的正确方法,但我在这里吓坏了,想知道为什么会发生这种情况。

提前谢谢你们。

【问题讨论】:

    标签: javascript javascript-objects


    【解决方案1】:

    在第一种方式中,您将原型替换为新原型(覆盖之前的原型)。在第二种方式中,您正在向原型添加一个新成员(从而扩展它)。

    还有另一种方法:具有extend 方法或类似方法的库(它基本上将您在第二种形式中所做的事情包装在一个很好的包装器中)。比如在jQuery:

    $.extend(obj_name.prototype, {
        newfoo : function() { alert('hi #3'); }
    }
    

    【讨论】:

      【解决方案2】:

      这是因为在行上

      obj_name.prototype = {
          newfoo : function() { alert('hi #3'); }
      }
      

      你创建一个新的原型对象,删除私有内容。好像你说过

      var a = {};
      

      当你像这样扩展对象时

      obj_name.prototype.newfoo = function() { alert('hi #3'); }
      

      它只是向对象树添加一个新属性(newfoo),保持现有内容不变。这就是它起作用的原因

      HTH

      伊沃·斯托伊科夫

      【讨论】:

      • 谢谢。我想我将 Amadan 的答案设置为我接受的答案是公平的。
      • +1 表示不需要 JQuery 来做一些简单的事情。
      【解决方案3】:

      不带 jQuery 的另一种选择:

      var extend = function(destination, source)
      {
          for (var property in source)
          {
              if (destination[property] && (typeof(destination[property]) == 'object')
                      && (destination[property].toString() == '[object Object]') && source[property])
                  extend(destination[property], source[property]);
              else
                  destination[property] = source[property];
          }
          return destination;
      }
      
      var a = {a: 'test'};                              // original
      var b = {newFoo: function() { alert('hi #3'); }}; // the addition
      extend(a, b);                                 // extend it
      a.newFoo();                                   // call the added property
      

      【讨论】:

      • 我的错,是的 ;) 希望也能有所帮助
      【解决方案4】:

      如果您正在寻找一个简单的轻量级库,它可以为您提供以下内容:OOP 在 javascript 中“正确完成”,请查看以下内容:https://github.com/haroldiedema/joii

      github页面上的自述文件中提供的源代码示例,以及这些链接:

      这个库基本上允许您这样定义“类”:

      var Person = Class(function() {
          this.firstname = "John"
          this.surname   = "Smith"
          this.role= "Developer"
      
          this.getInfo = function() {
              return this.firstname + ' ' + this.surname + ' is ' + this.role;
          };
      });
      
      var AnotherPerson = Class({ extends: Person }, function() {
          this.firstname = "Bob";
      });
      
      var p = new AnotherPerson();
      console.log(p.getInfo());
      // Bob Smith is Developer
      

      编辑

      以您的代码为例,但转换为兼容 JOII 的代码,它看起来完全像这样:

      var obj_name = Class(function() {
          this.foo = function() { alert('hi!'); };
          this.foo2 = function() { alert('hi again!'); };
      };
      
      var obj_name2 = Class({ extends: obj_name }, function() {
          this.newfoo = function() { alert('hi #3'); };
      });
      
      var o = new obj_name2();
      o.foo(); // hi!
      o.newfoo(); // hi #3
      

      或将其用作混合:

      var o = new obj_name();
      o.mixin(obj_name2);
      
      o.newfoo(); // hi #3
      

      或者反过来,使用“特质”。

      // the "uses" option basically copies content from the given object to the scope of your "class", solving the horizontal code-reuse problem.
      var obj_name = Class({ uses: [obj_name2], function() {
          this.foo = function() { alert('hi!'); };
          this.foo2 = function() { alert('hi again!'); };
      });
      
      var o = new obj_name();
      o.newfoo(); // hi #3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多