替代(或相同?)作为JavaScript原型

时间:2014-03-31 15:03:33

标签: javascript prototype

我想了解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();

我得到 obj1 obj2 。那么,我在 2)所做的也是原型?或不?我对原型缺少什么?

3 个答案:

答案 0 :(得分:4)

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也有对原型对象的引用,所以你也得到了&#39; 2&#39;通过调用函数fn

此处所有实例共享相同的原型对象。


<强> 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功能。如果一个对象更改了该函数,它将只影响当前对象。

答案 1 :(得分:2)

obj1和obj2略有不同,我将给你一个关于JavaScript中prottypal继承的快速解释。

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

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

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

为什么obj1和obj2不同?

obj1没有直接引用fn方法,而是持有对原型的引用,该原型具有该方法,因此obj1也有它。

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

您可以通过更改原型的方法来更改obj1的fn方法,并且还将更改MyObject的任何其他实例(如obj1)。

但你不能在obj2中这样做,如果修改obj2的方法,你只需要替换该实例的方法。

我希望你有所收获,只要问你是否有任何疑问。

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

答案 2 :(得分:1)

说我们有

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
  1. 我们可以从中学到什么? 跨实例进行原型共享,但不直接在它们上设置属性,而在构造函数中设置属性每次都会创建新的和单独的属性。