代码之家  ›  专栏  ›  技术社区  ›  iangraham

在javascript中扩展子对象

  •  1
  • iangraham  · 技术社区  · 16 年前

    我已经了解了更多关于JavaScript原型继承的知识。我知道关于是否扩展本地对象有一个激烈的争论,我想在这个问题上完全站在整个争论的一边。

    是否可以在javascript中只扩展子对象?

    要扩展所有对象,我可以这样做:

    Object.prototype.size = function(){
          var length = 0;
          for(var i in this){
               if(this.hasOwnProperty(i)){
                  length++;
               }
          }
          return this;
     }
    

    但问题是它扩展了所有对象。我想做的是:

    var MyNameSpace = function(){
    
    };
    
    MyNameSpace.Object.prototype.size = function(){
         var length = 0;
         for(var i in this){
             if(this.hasOwnProperty(i)){
                 length++;
             }
         }
         return this;
    }
    

    这样,我将只扩展全局对象范围内的本机对象。

    有什么建议吗?谢谢。

    更新:
    为了回应一些评论,我添加了更多的代码来澄清我想做什么。

    我想我可能没有正确地表达我的问题,或者我的想法不正确,但是我想做的是:

    
        var my = new MyNameSpace();
        var my.name = {firstName : 'Hello', lastName : 'World'};
        var nameCount = my.name.size(); // 2
    
    

    您提供的代码将允许我获取所创建的每个MyNamespace对象的大小,但不获取属于MyNamespace对象属性的对象文本。

    2 回复  |  直到 16 年前
        1
  •  1
  •   bryantsai    16 年前

    您可以使用“伪经典”继承样式来实现它:

    var MyNameSpace = function() {
      this.v1 = null;
      this.v2 = null;
    }
    
    MyNameSpace.prototype.size = function() {
      var length = 0;
      for(var i in this){
        if(this.hasOwnProperty(i)){
          length++;
        }
      }
      return this;
    }
    
    var my = new MyNameSpace(); // create new object based on MyNameSpace
    my.size(); // length would be 2
    

    在函数对象上定义的内容 prototype 将由通过创建的所有函数对象继承 new 操作员。

    更新的 代码,根据您添加的要求,

    var obj = {};
    
    var MyNameSpace = function(props) {
      for(var name in props) {
        this[name] = props[name];
      }
    }
    
    MyNameSpace.prototype.size = function() {
      var length = 0;
      for(var i in this){
        if(this.hasOwnProperty(i)){
          length++;
        }
      }
      return this;
    }
    
    obj.name = new MyNameSpace({firstName : 'Hello', lastName : 'World'});
    obj.name.size(); // length would be 2
    
        2
  •  0
  •   Andreas Jansson    16 年前

    在您的代码中

    var my = new MyNameSpace();
    var my.name = {firstName : 'Hello', lastName : 'World'};
    var nameCount = my.name.size(); // 2
    

    my.name 显然可以从 my 但事实并非如此。这意味着 我的 无法从访问 我的名字 我的 在原型链中找不到 我的名字 . 如果不想直接从mynamespace继承,则必须显式地“挂起”要继承的任何函数。

    你可以做到

    my.name.size = my.size;
    

    或者(不必实例化mynamespace):

    my.name.size = MyNameSpace.prototype.size;
    

    如果您只有很少的函数可以“继承”。或者您可以在mynamespace中定义一个继承函数,如下所示:

    MyNameSpace.prototype.addToNameSpace = function(obj) {
      obj.size = this.size;
      // obj.propertyI = this.propertyI, etc.
    }
    

    注意我不使用 for..in 这里,因为这会增加 addToNameSpace 功能也一样。

    希望这有帮助