function Human(age){
this.age = age
this.name = 'human'
this.color=['red','green']
}
function Worker(job){
this.job = job
}
// 原型链继承
Worker.prototype = new Human()
var a = new Worker('cook'),
b = new Worker('coder');
console.log(Worker.prototype.constructor.name)
console.log(a.name)
a.color.push('black')
console.log(b.color)
output:
Human
human
["red", "green", "black"]
缺点:不能向父类传递参数,引用类型的值会被所有实例共享,构造函数名被改写
借用构造函数
function Human(age){
this.age = age
this.name = 'human'
this.color=['red','green']
}
function Worker(job){
Human.call(this)
this.job = job
}
var a = new Worker('cook'),
b = new Worker('coder');
console.log(Worker.prototype.constructor.name)
console.log(a.name)
a.color.push('black')
console.log(b.color)
output
Worker
human
["red", "green"]
缺点:直接将父类属性写在了子类属性上,方法都需要在构造函数内定义
组合继承
原型链+借用构造
function Human(age){
this.age = age
this.name = 'human'
this.color=['red','green']
}
function Worker(job,age){
Human.call(this,age)
this.job = job
}
//继承方法
Worker.prototype = new Human()
Worker.prototype.constructor = Worker
Worker.prototype.getAge = function(){
return this.age
}
var a = new Worker('cook',23),
b = new Worker('coder',25);
console.log(Worker.prototype.constructor.name)
console.log(a.getAge())
console.log(b.age)
//基于已有对象创建,不需要创建自定义类型,不创建构造函数,
function object(o){
function F(){}
F.prototype = o
return new F()
}
//ES5中Object.create()的实现.
寄生式
// 通过一个中间函数F拷贝o的prototype到新对象的__proto__上,
function object(o){
// 空函数F:
function F(){}
// 把F的原型指向o:
F.prototype = o
// 返回的F对象的__proto__指向o.prototype:
return new F()
}
function createAnother(original){
var clone = object(original)
clone.sayHi = function(){
//....
}
return clone
}
不能做到函数复用,降低效率
寄生组合式继承
function object(o){
function F(){}
F.prototype = o
return new F()
}
function inheritPrototype(subType,superType){
var prototype = object(superType.prototype)
prototype.constructor = subType
subType.prototype = prototype
}
//eg
function Human(age){
this.age = age
this.name = 'human'
this.color=['red','green']
}
function Worker(job,age){
Human.call(this,age)
this.job = job
}
// 原型链继承
inheritPrototype(Worker,Human)
var a = new Worker('cook'),
b = new Worker('coder');
console.log(Worker.prototype.constructor.name)
console.log(a.name)
a.color.push('black')
console.log(b.color)
原型链继承
缺点:不能向父类传递参数,引用类型的值会被所有实例共享,构造函数名被改写
借用构造函数
缺点:直接将父类属性写在了子类属性上,方法都需要在构造函数内定义
组合继承
原型链+借用构造
最常用,instanceof 和 isPrototypeOf() 也可以识别. 缺点:调用了两次父类的构造函数子类属性上会包括父类上面所有的属性,这个也就是借用构造函数的缺点。
原型式继承
寄生式
不能做到函数复用,降低效率
寄生组合式继承
这里只是暂时了解了继承的几种形式, js在设计的时候就不具有面向对象的思想,为了赋予这种面向对象的能力,在语言发展路上进行了进化。 需要有扎实的基础和实际的应用才能深入体会去设计出这些继承模式的思想。
参考资料