我想了解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)所做的也是原型?或不?我对原型缺少什么?
答案 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 = fn2
但X.fn(); // 1
A.fn = fn2
现在A.fn(); // 2
但B.fn(); // 1
X.fn = fn2
现在X.fn(); // 2
但Y.fn(); // 1
"fn" in A; // true
但A.hasOwnProperty("fn"); // false
"fn" in X; // true
和X.hasOwnProperty("fn"); // true
我们可以从中学到什么? 跨实例进行原型共享,但不直接在它们上设置属性,而在构造函数中设置属性每次都会创建新的和单独的属性。