每个构造函数都有一个原型对象,原型对象又包含有个指向构造函数的指针,而实例则包含一个原型对象的指针(内存空间是共享的,当一个发生变化的时候,另一个也随之变化,构造函数的指向也发生变化)
1.原型链继承
每个构造函数都有一个原型对象,原型对象又包含有个指向构造函数的指针,而实例则包含一个原型对象的指针(内存空间是共享的,当一个发生变化的时候,另一个也随之变化,构造函数的指向也发生变化)
function Parent1(){
this.name = 'parent1'
this.play = [1,2,3]
}
function Child1(){
this.type = 'child2'
}
Child1.prototype = new Parent1()
console.log(new Child1())
var s1 = new Child1()
var s2 = new Child1()
s1.play.push(4)
console.log(s1.play,s2.play) // [1,2,3,4] [1,2,3,4]
2.构造函数继承 (借助call)
function Parent1(){
this.name = 'parent1'
}
Parent1.prototype.getName = function(){
return this.name
}
function Child1(){
Parent1.call(this)
this.type = 'child1'
}
let child = new Child1()
console.log(child) // {name:'parent1',type:'child1''}
console.log(child.getName()) //报错
3.组合继承
function Parent3(){
this.name = 'parent3'
this.play = [1,2,3]
}
Parent3.prototype.getName = function (){
return this.name
}
function Child3(){
Parent3.call(this)
this.type = 'child3'
}
Child3.prototype = new Parent3()
Child3.prototype.constructor = Child3
var s3 = new Child3()
var s4 = new Child3()
s3.play.push(4)
console.log(s3.play,s4.play) // [1,2,3,4] [1,2,3]
console.log(s3.getName()) // parent3
console.log(s4.getName()) // parent3
4. 圣杯模式
function inherit(Target,Origin){
function F(){}
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constuctor = Target
Target.prototype.uber = Origin.prototype
}
//上面的函数可以这样写
var inherit = (function (){
var F = function (){}
return function(Target,Origin){
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constuctor = Target
Target.prototype.uber = Origin.prototype
}
}())
// 这样写,是利用闭包让F()私有化
function Father(){}
function Son(){}
inherit(Son,Father)
var son = new Son()
var father = new Father()
Object.create() 和 new的区别:
// new
function Parent(){
this.name = 'parent'
this.play = [1,2,3]
}
function Child(){
this.type = 'child'
}
var parent = new Parent()
Child.prototype = parent
Child.prototype.constructor = Child
let child = new Child();
console.log(parent.constructor === child.constructor)
parent.constructor === child.constructor // true 都指向Child
// Object.create()
function Parent(){
this.name = 'parent'
this.play = [1,2,3]
}
function Child(){
this.type = 'child'
}
let parent = new Parent();
Child.prototype = Object.create(new Parent())
Child.prototype.constructor = Child
let child = new Child();
console.log(parent.constructor === child.constructor)// false
Object.create就是这种写法,也是Object.create的原生写法:
function Parent(){
this.name = 'parent'
this.play = [1,2,3]
}
function Child(){
this.type = 'child'
}
let parent = new Parent();
Child.prototype = parent
var F = function() {} //
let f = new F(); //
F.prototype = Parent.prototype //这四行就是Object.create
Child.prototype = new F(); //
Child.prototype.constructor = Child; //
let child = new Child(); //
console.log(parent.constructor === child.constructor) // false 指向各自的构造函数