js中任何一个函数都存在一个prototype属性,这就是原型对象,他本身也自带两个属性:constructor
和 __proto_
;
constructor: 这个属性是指向创建此对象的构造函数的引用,构造函数的实例化对象,也可以通过constuctor属性来访问构造它的那个函数;
proto: 这个属性指向创建此对象的构造函数的prototype原型对象的引用;
function Parent(){
this.name = 'mo'
}
Parent.prototype.work = function(){
return 'musicing'
}
var me = new Parent()
console.log(me.work()) // 'musicing'
var myBrother = new Parent()
console.log(myBrother.work()) // 'musicing'
console.log(me.work() === myBrother.work()) // true
原型链
在访问 me 的 work 方法时,找不到, 就会顺着_protp_属性往上在构造函数的prototype找,找到了就停止,没找到继续往上到Object.prototype找,再没找到就到null了,自然也找不到就只能返回undifined,这种链式的引用就是原型链。
继承的几种方式
(1) 原型链继承
原型链继承是通过 new实例化构造函数 赋给子类的原型, 其实实例的子类本身是完全的空对象,所有的属性方法都需要去原型链上找。
function Grandpa(){
this.name = 'mo'
}
Grandpa.prototype.work = function(){
return 'musicing'
}
function Parent(){} //创建一个空对象
Parent.prototype = new Grandpa()
var me = new Parent()
console.log(me.work()) // 'musicing'
var myBrother = new Parent()
console.log(myBrother.work()) // 'musicing'
console.log(me.work() === myBrother.work()) // true
(2) 构造函数继承
构造函数继承 通过apply去调用父类的构造函数,达到继承父类的实例属性,对,只能继承属性,要想继承方法 采用寄生组合继承
function Grandpa(firstname){
this.name = 'mo ' + firstname
}
Grandpa.prototype.work = function(){
return 'musicing'
}
function Parent(firstname){
Grandpa.apply(this, arguments)
}
Parent.prototype = new Grandpa()
var me = new Parent('alice')
console.log(me.work()) // ‘musicing’
var myBrother = new Parent('bob')
console.log(myBrother.work()) // ‘musicing’
console.log(me.work() === myBrother.work()) // true
console.log(me.name === myBrother.name)//false
(3) 寄生组合继承
寄生组合继承是我们经常要用到的,组合了原型和构造函数,结合Object.create(obj),方法对传入的对象进行浅拷贝,这样可以实现对实例属性和原型属性分别进行继承
function Grandpa(firstname){
this.name = 'mo ' + firstname
}
Grandpa.prototype.work = function(){
return 'musicing'
}
function Parent(firstname){
Grandpa.apply(this, arguments)
}
Parent.prototype = Object.create(Grandpa.prototype); // Object.create()将父级对象的属性和方法进行引用
Parent.prototype.constructor = Parent; //将该函数的construnctor指向parent构造函数
console.log(Parent.prototype);
var me = new Parent('alice');
var myBrother = new Parent('bob');
console.log(me.work() === myBrother.work()) // 'true'
console.log(me.name === myBrother.name)// 'false'