注意:
1,constructor總是指向類的構(gòu)造函數(shù)
2,__proto__指向父類的原型對(duì)象
1臣樱,原型鏈繼承
function Father(name){
this.name=name;
this.color=['red','blue'];
}
Father.prototype.getName=function(){
console.log(this.name)
}
function Child(){}
Child.prototype = new Father();
Child.prototype.constructor = Child;
var son1 = new Child('ming');
var son2 = new Child('wei');
son1.color.push('white');
son2.color; //['red','blue','white']
缺點(diǎn):對(duì)于復(fù)雜數(shù)據(jù)類型color,多個(gè)實(shí)例對(duì)引用的操作會(huì)被篡改
2,借用構(gòu)造函數(shù)繼承
function Father(name){
this.name=name;
}
Father.prototype.getName=function(){
console.log(this.name)
}
function Son(name){
Father.apply(this,arguments);
}
var son = new Son('ming');
console.log(son.getName()) // son.getName is not a function
缺點(diǎn):父類原型鏈上的屬性和方法無法獲取
3雇毫,組合繼承(偽經(jīng)典繼承)
function Father(name) {
this.name = name;
this.color=['red','blue'];
}
Father.prototype.getName = function() {
console.log(this.name)
}
function Child(name) {
Father.apply(this, arguments);
}
Child.prototype = new Father();
Child.prototype.constructor = Child;
var son = new Child('ming');
console.log(son.color);
son.color.push('white')
var son2 = new Child('wei');
console.log(son2.color) //['red','blue']
基本ok,除了new Father()那個(gè)地方會(huì)多寫一遍屬性和方法,差不多還行
4玄捕,原型式繼承(道爺-2006)
var Person={
name:'ming',
color:['red','blue']
}
function object(obj){
function F(){};
F.prototype=obj;
return new F();
}
var son1 = object(Person);
var son2 = object(Person);
son1.name='wei';
son1.color = ['white'];
console.log(son2.color); // ['red','blue','white']
缺點(diǎn)很明顯:
1,原型實(shí)例指向的引用相同,可能存在篡改
2,不能傳遞參數(shù)
另:object方法已經(jīng)由Object.create()實(shí)現(xiàn)
5棚放,寄生式繼承枚粘,(道爺有點(diǎn)皮)
創(chuàng)建一個(gè)函數(shù),在內(nèi)部構(gòu)造新的屬性和方法飘蚯,以增強(qiáng)對(duì)象(原型式繼承的加強(qiáng)版)
var Person = {
name: 'ming',
color: ['red', 'blue']
}
function object(obj) {
function F() {};
F.prototype = obj;
return new F();
}
function createSon(obj){
var son = object(obj);
console.log(son)
son.say=function(){
console.log('Hello,'+this.name)
}
return son;
}
var son1 = createSon(Person);
console.log(son1.name)
缺點(diǎn)很明顯:
1,原型實(shí)例指向的引用相同馍迄,可能存在篡改
2,不能傳遞參數(shù)
6,寄生組合式繼承(借用構(gòu)造函數(shù)繼承+寄生式繼承)
function object(obj) {
function F() {};
F.prototype = obj;
return new F();
}
function inheritPerson(Person,Son){
var pro = object(Person.prototype);
Son.prototype.constructor=Son;
Son.prototype = pro;
}
function Person(name){
this.name=name;
this.color=['red','blue'];
}
Person.prototype.say=function(){
console.log('Hello,'+this.name)
}
function Son(name,age){
Person.call(this,name);
this.age = age;
}
inheritPerson(Person,Son);
Son.prototype.getAge=function(){
console.log(this.age);
}
var child1 = new Son('ming',20);
var child2 = new Son('wei',30);
child1.say() // ming
child1.color.push('white');
console.log(child2.color) //['red','blue']
這個(gè)是es5的終極解決方案
7局骤,混入方式繼承多個(gè)對(duì)象
function Father1(name){this.name=name}
function Father2(age){this.age=age}
function Son(name,age){
Father1.call(this,name);
Father2.call(this,age);
}
Son.prototype = Object.create(Father1.prototype);
Object.assign(Father1.prototype,Father2.prototype);
Son.prototype.constructor=Son;
var son1 = new Son('ming',20);
console.log(son1)
這個(gè)實(shí)際上是寄生組合式繼承的加強(qiáng)版
8.class繼承
class Person{
constructor(name){
this.name=name
}
say(){
console.log(this.name)
}
}
class Son extends Person{
constructor(name){
super(name)
}
}
使用babel轉(zhuǎn)義為es5之后:
"use strict";
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var Person =
function () {
function Person(name) {
this.name = name;
}
var _proto = Person.prototype;
_proto.say = function say() {
console.log(this.name);
};
return Person;
}();
var Son =
function (_Person) {
_inheritsLoose(Son, _Person);
function Son(name) {
return _Person.call(this, name) || this;
}
return Son;
}(Person);
總結(jié):
1攀圈,類方法調(diào)用時(shí)不會(huì)變量提升:
var p = new P(); // Cannot access 'P' before initialization
class P{}
2,es6的繼承赘来,實(shí)際上是先創(chuàng)建父類的實(shí)例對(duì)象this凯傲,然后再用子類的構(gòu)造函數(shù)修改this,因此在子類的contructor中要調(diào)用父類的super()幌缝,否則要報(bào)錯(cuò)诫欠。
參考資料:
1,https://juejin.im/post/5bcb2e295188255c55472db0#heading-0
2缘厢,https://www.liaoxuefeng.com/wiki/1022910821149312/1023021997355072