【问题标题】:Javascript Inheritance and ArraysJavascript 继承和数组
【发布时间】:2010-06-07 13:37:57
【问题描述】:

我正在尝试定义一个带有数组属性的 javascript 类及其子类。问题是子类的所有实例都以某种方式“共享”数组属性:

// class Test
function Test() {
    this.array = [];
    this.number = 0;
} 

Test.prototype.push = function() {
   this.array.push('hello');
   this.number = 100;
}

// class Test2 : Test
function Test2() {
}

Test2.prototype = new Test();

var a = new Test2();
a.push(); // push 'hello' into a.array

var b = new Test2();
alert(b.number); // b.number is 0 - that's OK
alert(b.array); // but b.array is containing 'hello' instead of being empty. why?

如您所见,原始数据类型没有这个问题...有什么建议吗?

【问题讨论】:

标签: javascript arrays inheritance


【解决方案1】:

当您编写Test2.prototype = new Test() 时,您创建了一个Test 实例,其中包含一个数组实例,每个Test2 实例都共享该实例。

因此,所有Test2 实例共享同一个数组。

您可以通过从Test2 构造函数调用基本Test 构造函数来解决此问题,这将为每个Test2 实例创建一个新的数组实例。

例如:

function Test2() {
    Test.call(this);
}

【讨论】:

    【解决方案2】:

    另一个相当不优雅的替代方法是将初始化代码从构造函数移动到方法并从两个构造函数中调用它:

    // class Test
    function Test() {
      this.init();
    } 
    
    Test.prototype.init = function() {
        this.array = [];
        this.number = 0;
    };
    
    Test.prototype.push = function() {
       this.array.push('hello');
       this.number = 100;
    };
    
    // class Test2 : Test
    function Test2() {
      this.init();
    }
    
    Test2.prototype = new Test();
    

    【讨论】:

      【解决方案3】:

      我唯一能想到的是数组是共享引用。应该有一个明显的解决方案,因为这种经典的 OOP 代码一直都是用 Javascript 实现的。

      【讨论】:

        【解决方案4】:

        JavaScript 没有经典的继承系统,它有一个原型继承系统。所以在 JavaScript 中技术上没有“类”的概念。

        对象继承自其他对象(所谓的原型对象),而不是抽象类。这样做的一个重要后果是,如果多个对象共享同一个原型,并且其中一个对象更改了原型中定义的属性,那么该更改将立即对所有其他对象生效。

        尝试像基于类一样使用 JavaScript 继承通常会让人头疼,因为你总是会发现这类问题。

        我知道这并不能真正回答您的特定问题,但在较高层次上,我建议您接受原型继承,而不是尝试使用“伪类”。即使一开始看起来很奇怪,您的代码也会更加可靠,并且您不会因为奇怪的原型链而浪费时间尝试理解此类奇怪的错误。

        观看 Douglas Crockford 解释继承的视频,该视频可在 Yahoo UI Theater 网站上在线获取。它改变了我用 JavaScript 编程的方式 :)

        http://video.yahoo.com/watch/111585/1027823(链接到第一部分)

        http://developer.yahoo.com/yui/theater/(所有视频)

        【讨论】:

          猜你喜欢
          • 2016-01-22
          • 1970-01-01
          • 2013-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多