目录
1.原型链
2.盗用构造函数
基本思路:在子类构造函数中调用父类构造函数
function Father(name) {
this.name = name;
this.wife = function () {
return 'taylor'
}
this.daughter = 'Camila'
//添加构造方法
this.constructFunction = function () {
console.log('我是构造方法')
}
}
function Son(name) {
this.name = name
this.mother = Father.wife
//传递参数
Father.call(this)
}
let instance = new Son()
// 不能直接访问方法
console.log(instance.mother) //underfined
Son.prototype = new Father()
// 可以直接访问
console.log(Son.prototype.wife())
3.组合继承
综合了原型链和盗用构造函数的优点,使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。
如果我想两个function()之间,调用和访问对方的方法和属性,用这!!
function Father(name) {
this.name = name;
this.wife = function () {
return 'taylor'
}
this.daughter = 'Camila'
//添加构造方法
this.constructFunction = function () {
console.log('我是构造方法')
}
}
function Son(name) {
this.name = name
this.mother = Father.wife
//传递参数
Father.call(this)
}
let instance = new Son()
// 不能直接访问方法
console.log(instance.mother) //underfined
Son.prototype = new Father()
// 可以直接访问
console.log(Son.prototype.wife())
4.原型式继承
适用情况:你有一个对象,想在它的基础上再创建一个新对象。你需要把这个对象先传给object(),然后再对返回的对象进行适当修改。
非常适合不需要单独创建构造函数,但仍需要在对象间共享信息的场合。但是,属性中包含的引用值始终会在相关对象间共享,跟使用原型模式是一样
function object(o){
function F(){}
F.prototype=o;
return new F();
}
let person = {
name: 'Nico',
friends: ['1', '2']
}
let aperson = Object(person)
aperson.name = 'Tom'
aperson.friends.push('Emma')
let bperson = Object(person)
bperson.name = 'John'
bperson.friends.push('Mary')
//可以发现 name属性以修改的最后那个为准
console.log(person)
let cperson = Object.create(person)
cperson.name = 'Taylor'
cperson.friends.push('camila')
let dperson = Object.create(person)
dperson.name = 'Taylor2'
dperson.friends.push('camila2')
//可以发现name属性没有修改到,所以遇到同名属性不会影响到
console.log(person)
console.log(dperson.name) //Taylor2
console.log(dperson.friends) //['1', '2', 'Emma', 'Mary', 'camila', 'camila2']
5.寄生式继承
创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。
function createAnother(original) {
let clone = Object(original);
clone.sayHi = function () {
console.log('hi')
}
return clone
}
let person = {
name: 'Nico',
friends: ['shelby', 'Court', 'Van']
}
let self = createAnother(person)
self.sayHi()
可以观察上面的代码,可以知道,可以任意给对象添加函数
6.寄生式组合继承
组合继承存在效率问题:父类构造函数始终会调用两次:一次在是创建子类原型时调用,另一次是在子类构造函数中调用
如下所示:
//组合继承
function Father(name){
this.name=name;
this.colors=['red','blue']
}
//创建一个原型方法
Father.prototype.sayName=function(){
console.log(this.name)
}
function children(name,age){
Father.call(this,name) //第二次调用Father()
this.age=age
}
children.prototype=new Father() //第一次调用Father()
children.prototype.constructor=children
children.prototype.sayAge=function(){
console.log(this.age)
}
寄生式组合继承--引用类型继承的最佳模式
这里值调用了一次SuperType构造函数,避免了SubType。prototype上不必要也用不到的属性,因此可以说这个粒子的效率更高。而且,原型链仍然保持不变,因此instanceof操作符合isPrototypeOf()方法正常有效
// 使用寄生式继承来继承父类原型,然后将返回的新对象赋值给子类原型
function inheritPrototype(SubType, SuperType) {
let prototype = Object(SuperType.prototype); //创建对象
prototype.constructor = SubType; //增强对象
SubType.prototype = prototype; //赋值对象
}
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue']
}
SuperType.prototype.sayName = function () {
console.log(this.name)
}
function SubType(name, age) {
SuperType.call(this, name)
this.age = age
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function () {
console.log(this.age)
}