【问题标题】:alternative (or the same?) as javascript prototype [duplicate]替代(或相同?)作为javascript原型[重复]
【发布时间】:2014-03-31 15:03:33
【问题描述】:

我想了解 javascript 中的原型设计。 例如:

1)

var MyObject = function() {
    this.a = "a";
    return this;
}

MyObject.prototype.fn = function() {console.log('1');}


var obj1 = new MyObject1();

2)

var MyObject = function() {
    this.a = "a";
    this.fn = function() {console.log('1');}
    return this;
}

var obj2 = new Object2();

我得到 obj1obj2 相同。那么,我在 2) 中所做的也是原型制作?或不?我对原型缺少什么?

【问题讨论】:

  • 只要把MyObject.prototype想象成一个由MyObject构造函数创建的所有对象共享的对象。因此,即使您从 MyObject 创建 1,000 个新对象,它们都将共享(继承).prototype 对象的所有属性。
  • 感谢所有 cmets 和答案。 +1。我必须选择一个作为答案。
  • 原型是共享的,this.fn 是为每个实例创建的。有关原型和继承的更多信息,请参见此处:stackoverflow.com/a/16063711/1641941

标签: javascript prototype


【解决方案1】:

2) 不是原型设计

这里是一个简单的例子,解释了两种方法的区别:


1)

var MyObject1 = function() {
    this.a = "a";
    return this;
}

MyObject1.prototype.fn = function() {console.log('1');}

var obj1 = new MyObject1();

// change the prototype again
MyObject1.prototype.fn = function() {console.log('2');}

var obj2 = new MyObject1();

obj1.fn(); // logs '2'
obj2.fn(); // logs '2'

这里您在创建obj1 后更改了原型对象,但此更改仍然会影响该对象,因为它具有对当前原型对象的引用。

因为obj2 也有对原型对象的引用,所以你也可以通过调用函数fn 得到'2'。

这里所有实例共享同一个原型对象。


2)

var MyObject2 = function() {
    this.a = "a";
    this.fn = function() {console.log('1');}
    return this;
}

var obj3 = new MyObject2();

// change the function
obj3.fn = function() {console.log('2');}

var obj4 = new MyObject2();

obj3.fn(); // logs '2'
obj4.fn(); // logs '1'

这里每个对象都有自己的fn 函数。如果一个对象改变了功能,它只会影响当前对象。

【讨论】:

    【解决方案2】:

    obj1 和 obj2 略有不同,我将简要介绍一下 JavaScript 中的原型继承。

    原型是一个对象,就像任何其他对象一样。

    每个拥有原型的对象都会继承它的所有属性和方法,如果它们已经在对象中定义,则覆盖它们。原型引用是实时的,这意味着,每当您修改作为另一个对象原型的对象时,更改都会反映在该对象中。

    您正在使用伪经典继承方法,通过这种方法您定义了一个Constructor 函数,该函数将返回一个“类”的实例。该类的所有实例都将在Constructor.prototype 处定义的对象作为其原型对象,并且您可以向该原型添加方法或属性,这些方法或属性将添加到“类”的每个实例中。

    为什么 obj1 和 obj2 不同?

    obj1 不直接引用fn 方法,而是保存对原型的引用,该原型具有该方法,因此 obj1 也具有该方法。

    obj2 直接引用该方法,这意味着它是对象自己的属性。

    您可以通过更改原型的方法来更改obj1的fn方法,MyObject的任何其他实例(如obj1)也会被更改。

    但是你不能在 obj2 中这样做,如果你修改了 obj2 的方法,你只会替换那个实例的方法。

    我希望你有所收获,如果你有任何疑问,请询问。

    关于“类”的写法:JavaScript 没有类,它用原型模拟类继承,你可以使用Object.create 使用粗略的原型继承,你会发现它更容易。

    【讨论】:

      【解决方案3】:

      说我们有

      var A = new Object1(),
          B = new Object1(),
          X = new Object2(),
          Y = new Object2(),
          fn2 = function () {
              console.log(2);
          };
      

      考虑(为每个重置)

        • A.fn === B.fn; // true
        • X.fn === Y.fn; // false
        • Object1.prototype.fn = fn2 然后A.fn(); // 2
        • Object2.prototype.fn = fn2X.fn(); // 1
        • A.fn = fn2 现在 A.fn(); // 2B.fn(); // 1
        • X.fn = fn2 现在 X.fn(); // 2Y.fn(); // 1
        • "fn" in A; // trueA.hasOwnProperty("fn"); // false
        • "fn" in X; // trueX.hasOwnProperty("fn"); // true

      我们可以从中学到什么?
      原型共享跨实例但不直接在它们上设置属性,而在构造函数中设置属性每次都会创建新的和单独的属性。

      【讨论】:

        猜你喜欢
        • 2011-03-25
        • 2013-04-08
        • 2019-01-24
        • 2016-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-28
        相关资源
        最近更新 更多