写在前面:因为还没开始工作,可能有的部分有错,希望大家能指点出来,这是我看渡一的视频总结的笔记,所有的示例都来自视频,我算是一个搬运工了吧哈哈哈视频讲的很好,强烈推荐大家去看一看ヾ(◍°∇°◍)ノ゙
继承模式
继承发展史
1.传统模式-原型链
缺点:
过多的继承了没用的属性,提升不到工业化的程度
示例:
Grand.prototype.lastName = 'Deng';
function Grand(){};
var grand = new Grand();
Father.prototype = grand;
function Father(){};
var father = new Father();
注:
1.一定要先继承再new
2.Father.prototype = grand;一定是小写的grand
大小写区别↓
/*-------student,Student对比---------
student↓
Student {name: "lin", age: 18, sex: "male", grade: "one"}
Student↓
ƒ Student(name,age,sex,grade) {
Person.call(this,'lin',18,'male');
this.grade = 'one'
}*/
2.借用构造函数(call/apply)
缺点:
1.不能继承借用构造函数的原型(call的this(Student)不能继承Person的原型)
2.每次构造函数都要多走一个函数(每构造一个对象都要执行两个方法Person,Student)
适用于:
工业开发:我的方法完全囊括了别人的方法
示例:
function Person(name,age,sex,) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,grade) {
Person.call(this,'lin',18,'male');
this.grade = 'one'
}
var student = new Student();
- 使用this的函数必须得是new出来的!!!(未深入理解)
3.公有原型
优点:
从继承的角度来看,这种方法最好
从根上继承,连原型也继承了
缺点:
不能随便改动自己的原型
示例:
father.prototype.lastName = 'Deng';
function Father(){};
function Son(){};
var son = new Son();
var father = new Father();
原来的原型链继承方式:
Son.prototype = father;//继承语句!!
//------在new前写这句↑!!!------------
现在的方法:
1.一对一继承
Son.prototype = Father.prototype;//继承语句!!!
现在Son,Father的原型都是Father , Father.prototype是一个对象,是引用值,引用值之间的赋值传地址,所以Father的原型改了,Son也会跟着改
2.抽象出一个功能,封装成一个函数(功能复用)
function inherit(Target,Origin) {
//Target继承Origin
Target.prototype = Origin.prototype;
}
(1)注意执行顺序
先继承再new:
inherit(Son,Father);
var son = new Son();
//son.lastName = 'Deng'
先new在继承:
var son = new Son();
inherit(Son,Father);
//son.lastName:undefined
后改原型,已经晚了,son已经指向自己了
结论:
一定是先继承后new!!
(2)
子孙可以删除长辈的原型
通过delete Son.prototype.lastName
可以删除Father.prototype.lastName
子孙可以修改长辈的原型
Son.prototype.sex = 'male'
结论:
Son.prototype 和 Father.prototype的指向一致,Son不能实现个性化自己的属性,Son一改(包括增删),Father也改了
4.圣杯模式
优点:
Son有自定义的属性,也有继承的公有属性,不影响Father
基本结构:
function F() {}
F.prototype = Father.prototype;
Son.prototype = new F();
现在Father.prototype是Father和F的公有原型,F充当一个中间人
Son通过原型链的方式继承F,即继承了Father
Son的原型是new F,F的原型才是Father
示例:
Father.prototype.lastName = 'Deng';
function inherrit2(Target,Origin) {
function F() {}
F.prototype = Origin.prototype;
Target.prototype = new F();
//想要改变son的constructor
Target.prototype.constructor = Target;
//查看真正继承自谁-超类
Target.prototype.uber = Origin.prototype;
}
inherrit2(Son,Father);
function Father() {
}
function Son() {
}
//函数声明写在哪都相当于在最顶端
var son = new Son();
var father = new Father();
Son.prototype.sex = 'male';
输出结果:
/*son.sex:"male"
father.sex:undefined*/
//Target.prototype.constructor = Target;改变了son.constructor
//son.constructor:ƒ Father() {}--->son.constructor:ƒ Son() {}
//查看真正继承自谁-超类
/*son.uber:
{lastName: "Deng", constructor: ƒ}
lastName: "Deng"
constructor: ƒ Father()
__proto__: Object*/
/*-----注意!!!错误写法↓
function F() {}
Son.prototype = new F();
F.prototype = Father.prototype;
考察原型指向问题 new的时候他用的是原来的原型,后再改已近晚了*/
son.__ proto__ --> new F().__ proto__–>Father.prototype
找不到原型就继续往下找
new F()对象没有constructor,F输不出来
- F不存在??(不理解)
还有个高级版的圣杯代码,是用立即执行的方法,但是我的没法正常执行,就不放出来了