繼承的發(fā)展史:
1辐烂、傳統(tǒng)模式——>原型鏈:
? ? ? ? ? ? 下圖是通過改變原型鏈的指向來實現(xiàn)繼承(子類的原型prototype等于父類的實例):
? ? ? ? ? ? 缺點:因為改變原型指向的同時實現(xiàn)繼承,并初始化了屬性或方法缸榄,繼承過來的屬性或方法都是一樣的,并且無法得到實例的對應的constructor祝拯,除非手動添加甚带,也過多繼承了無用的屬性(包括父類私有和共有屬性和方法)。
2佳头、借用構造函數(shù)(繼承的時候不用改變原型的指向鹰贵,直接調(diào)用別的構造函數(shù)的方式來為屬性或方法賦值):
? ? ? ? ? ? //這是個反例,通過原型鏈繼承所造成的問題
? ? ? ? ? ? function? ? Person(name,sex){
? ? ? ? ? ? ? ? ? ? this.name = name;
? ? ? ? ? ? ? ? ? ? this.sex = sex;
? ? ? ? ? ? }
? ? ? ? ? ? Person.prototype.say = function () { console.log("hello") };
? ? ? ? ? ? function? ? Student(score){
? ? ? ? ? ? ? ? ? ? this.score = score
? ? ? ? ? ? }
? ? ? ? ? ? Student.prototype = new Person(”hello“康嘉,"boy")碉输;
? ? ? ? ? ? var? ? student1= new? ? Student(90);? ? //student1: { name:"hello",sex:"boy",score:90}
? ??????????var? ? student2 = new? ? Student(98);? //student2: { name:"hello",sex:"boy",score:98}?
? ??????????var? ? student3 = new? ? Student(100);//student3: { name:"hello",sex:"boy",score:100}
? ? ? ? ? ? //這樣就造成了Student的所有實例部分屬性或方法一樣,需要手動為實例更改屬性或方法才可以有不同的屬性值亭珍,為了解決這個問題敷钾,我們可以通過借用構造函數(shù)實現(xiàn)繼承
? ??????????通過call來借用構造函數(shù):
? ? ? ? ? ? //改造上面的反例
? ???????????function? ? Student(name,sex,score){? ? ? ??
? ? ? ? ? ? ? ? ? ? Person.call(this,name,sex);? ? //通過call來借用構造函數(shù)
? ? ? ? ? ? ? ? ? ? this.score = score;
? ? ? ? ? ? }
? ? ? ? ? ? //借用構造函數(shù)不能繼承該函數(shù)的原型對象枝哄,因此定義在改構造函數(shù)原型的方法不能被借用
3、共享原型:
? ? ? ? ? ? 缺點:一方改變原型都會影響到另外一方
4阻荒、圣杯模式:
5挠锥、組合繼承(原型繼承+借用構造函數(shù)繼承):