原型
-
概念
- 每个对象都有自己的
prototype
属性,称为原型对象,如果原型对象不为null
,那么这个原型对象里面有一个__proto__
属性会指向自己的原型,此时就产生了原型链
- 每个对象都有自己的
-
作用
- 把一些方法定义在
prototype
对象上,这样所有对象的实例就可以共享这些方法,节约内存
- 把一些方法定义在
继承
-
构造函数继承 (实现对实例属性的继承)
-
通过
call()
或者apply()
方法改变父构造函数的this -
function Father() { this.head = '头' this.foot = '脚' this.say = function () { console.log('hello'); } } function Son(name, age) { this.name = name this.age = age Father.call(this) // 用call继承Father } const son = new Son('刘德华', 18) son.say() //hello console.log(son.name); //刘德华 console.log(son.age); //18 console.log(son.head); //头 console.log(son.foot); //脚
-
-
通过原型链的方式继承 (实现对原型对象属性和实例属性的继承)
-
function Father() { this.head = '头' this.foot = '脚' } Father.prototype.say = function () { console.log('hello'); } function Son(name, age) { this.name = name this.age = age } Son.prototype = new Father() //用原型链的方式,子类的原型对象=父类的的实例,此方法会导致子类原型的constructor丢失,所以需要手动添加constructor Son.prototype.constructor = Son //把原型对象指回Son const son = new Son('刘德华', 18) son.say() //hello console.log(son.name); //刘德华 console.log(son.age); //18 console.log(son.head); //头 console.log(son.foot); //脚
-
-
通过原型直接继承 (实现对原型对象属性的继承,会造成原型链混乱,所以进行特殊处理)
-
function Father() { this.hand = '手' } Father.prototype.head = '头' Father.prototype.foot = '脚' Father.prototype.say = function () { console.log('hello'); } function Son(name, age) { this.name = name this.age = age } //原始的做法 Son.prototype = Father.prototype //优点:比较节约内存 不用new一个Father实例对象 //缺点:会造成继承链的混乱 即Son.prototype.constructor //与Son.prototype.constructor相等,这样是不合理的 //所以可以进行封装 解决混乱问题 function extend(Child, Parent) { const F = function () { } //1搞一个空对象 F.prototype = Parent.prototype //2空对象作为中介来接收父类的原型对象 Child.prototype = new F() //3子类通过new这个空对象实例间接继承父类 Child.prototype.constructor = Child //4子类指回自身构造函数 } extend(Son, Father) //直接调用封装好的继承函数 const son = new Son('刘德华', 18) son.say() //hello console.log(son.name); //刘德华 console.log(son.age);//18 console.log(son.head); //头 console.log(son.foot); //脚 console.log(son.hand); //undefined
-
-
组合继承 (实现对原型对象属性和实例属性的继承)
-
把构造函数继承和原型链继承相结合
-
function Father() { this.head = '头' } Father.prototype.hobby = function () { console.log('喝酒'); } function Son(name) { Father.call(this) this.name = name } Son.prototype = new Father() Son.prototype.constructor = Son const son = new Son('刘德华') console.log(son.name); //刘德华 console.log(son.head); //头 son.hobby() //喝酒
-
-
拷贝继承(实现原型对象属性的继承)
-
function Father() { this.head = '头' } Father.prototype.hobby1 = '喝酒' Father.prototype.hobby2 = '抽烟' function Son(name) { this.name = name } Object.assign(Son.prototype, Father.prototype) const son = new Son('刘德华') console.log(son.name); //刘德华 console.log(son.hobby1);//喝酒 console.log(son.hobby2);//抽烟 console.log(son.head); //undefined
-