创建 javascript 原型继承链的不同方式
Different ways of creating javascript prototype inheritance chain
function Parent(parentName){
this.name = parentName;
}
Parent.prototype.printName = function(){
console.log(this.name);
}
var p = new Parent("Parent");
console.log(p);
function Child(parentName, childName){
Parent.call(this, parentName);
this.name = childName;
}
1. Child.prototype = Object.create(Parent.prototype);
2. Child.prototype = Parent.prototype;
var c = new Child("Parent","Child");
console.log(c);
有人能告诉我上述语句 1 和 2 之间的区别吗。无论哪种方式,子对象都可以调用 c.printName();
两者区别很大,
原型最令人困惑的部分之一是你有原型和 proto.
Protoype是一个特殊的属性函数object,每当你用new关键字调用构造函数时,实例proto,将成为构造函数原型。
Object.create 是允许您创建新 object 的方法,并将其指定为 proto.
因此,当通过方法 1 分配 Child class 原型时,您将给 child class 一个全新的原型 object,即通过protolink,parent的方法通过原型继承来继承。
这是更好的选择,因为您可以在不影响 parent 原型的情况下对 child 原型进行修改,因为它是一个不同的 object.
另一方面,选项 2
您正在为两个 class 分配相同的原型,它们都 引用相同的 object, 因此对 child 原型的更改将影响 parent 原型,这通常不是理想的情况,也不是一个好的做法。
方法一的例子:
Child.prototype = Object.create(Parent.prototype);
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 1');
console.log('Child.prototype = Object.create(Parent.prototype);');
Child.prototype = Object.create(Parent.prototype);
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('yay parent is still working');
方法 2 的示例:
Child.prototype = Parent.prototype;
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 2');
console.log('Child.prototype = Parent.prototype;');
Child.prototype = Parent.prototype;
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('oops we broke parent');
1和2的区别在于
第一个你正在创建一个新的 object 具有指定的原型 object 和属性,不与 parent
共享
Object.create(Parent.prototype)
的作用是 returns 一个 新的 object 与 parent 的原型,但是第二个一个你只是引用(指向)child原型到parent原型,所以如果你添加一个属性到child 原型说,
Child.prototype.age = function(){
console.log("parent can access this method");
}
p.age();
parent can access this method gets printed, 对于经典继承,您可能希望使用第一种方法,但第二种方法有一些用例
只是对此进行扩展post,我认为最好的继承方式是
// parent object
var Parent = {
firstname: "john",
getFirstName : function () {
console.log(this.firstname);
}
};
// create a child object with all the properties and methods of Parent
var child = Object.create(Parent);
// add or modify child properties
child.lastname = "doe";
child.getLastName = function () {
console.log(this.lastname);
};
// create instances of child object
baby1 = Object.create(child);
baby1.firstname = "alice";
baby1.getFirstName();
baby1.getLastName();
// to see the prototype chain
console.log("baby1 properties: ", baby1);
console.log("baby1 parent properties: ", baby1.__proto__);
console.log("baby1 grandpa properties: ", baby1.__proto__.__proto__);
非常简单,无需调用或手动原型管理
function Parent(parentName){
this.name = parentName;
}
Parent.prototype.printName = function(){
console.log(this.name);
}
var p = new Parent("Parent");
console.log(p);
function Child(parentName, childName){
Parent.call(this, parentName);
this.name = childName;
}
1. Child.prototype = Object.create(Parent.prototype);
2. Child.prototype = Parent.prototype;
var c = new Child("Parent","Child");
console.log(c);
有人能告诉我上述语句 1 和 2 之间的区别吗。无论哪种方式,子对象都可以调用 c.printName();
两者区别很大, 原型最令人困惑的部分之一是你有原型和 proto.
Protoype是一个特殊的属性函数object,每当你用new关键字调用构造函数时,实例proto,将成为构造函数原型。
Object.create 是允许您创建新 object 的方法,并将其指定为 proto.
因此,当通过方法 1 分配 Child class 原型时,您将给 child class 一个全新的原型 object,即通过protolink,parent的方法通过原型继承来继承。 这是更好的选择,因为您可以在不影响 parent 原型的情况下对 child 原型进行修改,因为它是一个不同的 object.
另一方面,选项 2 您正在为两个 class 分配相同的原型,它们都 引用相同的 object, 因此对 child 原型的更改将影响 parent 原型,这通常不是理想的情况,也不是一个好的做法。
方法一的例子:
Child.prototype = Object.create(Parent.prototype);
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 1');
console.log('Child.prototype = Object.create(Parent.prototype);');
Child.prototype = Object.create(Parent.prototype);
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('yay parent is still working');
方法 2 的示例:
Child.prototype = Parent.prototype;
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 2');
console.log('Child.prototype = Parent.prototype;');
Child.prototype = Parent.prototype;
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('oops we broke parent');
1和2的区别在于
第一个你正在创建一个新的 object 具有指定的原型 object 和属性,不与 parent
共享Object.create(Parent.prototype)
的作用是 returns 一个 新的 object 与 parent 的原型,但是第二个一个你只是引用(指向)child原型到parent原型,所以如果你添加一个属性到child 原型说,
Child.prototype.age = function(){
console.log("parent can access this method");
}
p.age();
parent can access this method gets printed, 对于经典继承,您可能希望使用第一种方法,但第二种方法有一些用例
只是对此进行扩展post,我认为最好的继承方式是
// parent object
var Parent = {
firstname: "john",
getFirstName : function () {
console.log(this.firstname);
}
};
// create a child object with all the properties and methods of Parent
var child = Object.create(Parent);
// add or modify child properties
child.lastname = "doe";
child.getLastName = function () {
console.log(this.lastname);
};
// create instances of child object
baby1 = Object.create(child);
baby1.firstname = "alice";
baby1.getFirstName();
baby1.getLastName();
// to see the prototype chain
console.log("baby1 properties: ", baby1);
console.log("baby1 parent properties: ", baby1.__proto__);
console.log("baby1 grandpa properties: ", baby1.__proto__.__proto__);
非常简单,无需调用或手动原型管理