本文仅提供总结
来自javascript 面向对象变成指南第二版
书中内容有部分错误 如182 页的
return const.uber?thisconst.uber +’,’+this.name:this.name
去掉 this才正确等等
原型链(传统)—能继承父对象的属性
大量可重用的方法和属性可设置在父链中 ,不同重用的设置为对象的自身属性
Child.prototype=new Parent();
只继承原型法 **
直接引用父链 优点查询快,效率好 缺点:修改子对象的方法或属性会**改变父链的方法或属性
Child.prototype=Parent.prototype
临时构造器法
类似只继承原型法效率差一点 优点是 修改子对象的方法或属性不会改变父链的方法或属性
var Temp=function(){};
Temp.prototype=Parent.prototype
Child.prototype=new Temp()
Child.prototype.constructor=Child #因为F修改了内建的prototype.constructor属性 这里进行重置
原型拷贝法
直接原型拷贝 而不再是引用 但是不能拷贝 对象类型(例如不会拷贝 prototype.constructor 属性,就不用重置)
var c=Child.prototype
var p=Parent.prototype
for (var i in p){
if p.hasOwnProperty(i){ #确保仅拷贝 p中的原型
c[i]=p[i]
}
} #这样就拷贝完成
全属性拷贝
非常简单
新增一个空对象c= {}
利用上面的for 循环进行拷贝
深度拷贝
创建一个空对象 进行拷贝 如果是’object’对象就 利用递归对Object对象进行拷贝
function DeepCopy(p,c){
var c=c||{};
for (var i in p){
if p.hasOwnProperty(i){ #确保仅拷贝 p中的原型
if(typeof p[i]==='object'){
c[i]=Array.isArray(p[i])?[]:{};
DeepCopy(p[i],c[i])
}
c[i]=p[i]
}
}
}
原型继承法
直接对父链的原型进行继承,返回一个新的对象 具有__proto__
创建一个中间器 用原型接收 然后 new出来
function object(Parent){
Temp=function(){};
Temp.prototype=Parent
n=new Temp()
return n
} #
扩展和增加模式
沿用上一种方法 用 objectPlus(Parent,{name:‘test’}) 这里stuff可以进行覆盖增加
function objectPlus(Parent,stuff){
Temp=function(){};
Temp.prototype=Parent
var n=new Temp()
for (var i in stuff){
n[i]=stuff[i]
}
}
多重继承方式
很简单 对每个父链进行遍历 赋值
function multi(){
var n={},stuff,j=0,len=arguments.length;
for (j=0;j<len;j++){
stuff=arguments[j]
for (var i in stuff){
n[i]=stuff[i]
}
}
}
寄生继承法
一个对象 victim={name:‘test’}
可以不用new 创建 因为本质是 普通函数
可以用 new 创建 (因为返回的that 是对象) 很巧妙
function parasite(victim){
new that=object(victim)
that.name='test'
return that
}
构造器和原型复制
利用构造器盗用 和原型复制 实现继承
Monkey(){
name='monkey'
}
Monkey.prototype.walk='run'
Thing(){
Monkey.apply(this,arguments,)
}
p=Monkey.prototype
c=Thing.prototype
for (var i in p){
c[i]=p[i]
}
var my=new Thing(101)