JS代码复用模式(继承,混合等)
简单继承
Children.prototype = new Parent()
特点:
- 继承父类方法的同时继承了父类的属性
- 大量继承时要反复创建父类的实例(避免修改父对象)
- 无法多重继承
借用构造函数
// 父类的构造函数 function Parent(name){ this.name = name } Parent.prototype.say = function(){/* ... */} // 子类的构造函数 function Children(name){ Parent.apply(this,argument) }
特点:
- 只能继承属性,无法继承原型方法
- 可以多重继承
借用和设置原型
// 父类的构造函数 function Parent(name){ this.name = name } Parent.prototype.say = function(){/* ... */} // 子类的构造函数 function Children(name){ Parent.apply(this,argument) } Children.prototype = new Parent()
特点:
- 父构造函数会调用两次,影响效率
- 只可以多重继承属性
共享原型
Children.prototype = Parent.prototype
特点:
- 效率高
- 子对象如果修改原型会影响父对象
- 要遵循可复用成员均转移到原型的原则
临时构造函数
// 闭包避免每次都创建F var inherit = (function (){ var F = function(){} return function (C,P){ F.prototype = P.prototype C.prototype = new F() // 超类(可选) C.uber = P.prototype // 重置构造函数指针 C.prototype.constructor = C } }())
特点:
- 无明显缺点
原型继承
var Parent = { name : "爸爸" } // ES5 var children = Object.create(parent)
复制属性
function extend(P,C){ var i C = C || {} for(i in P){ if(P.hasOwnProperty(i)){ if(typeof P[i] === "object"){ C[i] = (Object.prototype.toString.call(P[i]) === "[object Array]") ? [] : {} extend(P[i],C[i]) }else{ C[i] = P[i] } } } return C }
特点:
- 可部分继承
- 可多重继承
混合(鸭子类型)
并不是所有时候都需要继承,继承也不是完美的,有时候会创造比他能解决的更多的问题,特别是当层次关系没那么明显的时候,
这时候应该多用结构类型(又叫鸭子类型),用结构类型设计灵活的对象接口的时候,不需要返回类的实例,而是直接返回对象,对象具备预期的方法和属性,比如:// 将传入的对象的属性打包成新对象 function mix(){ var child = {} for(var arg = 0, len = argument.length; arg < len; arg++){ for(var prop in argument[arg]){ if(argument[arg].hasOwnProperty(prop)){ child[prop] = argument[arg][prop] } } } return child }
借用
即是call()/apply()绑定
// ES5 // 后面为预填充参数 // 执行newFun相当于执行obj.someFun.call(myobj, 1, 2, 3) var newFun = obj.someFun.bind(myobj, 1, 2, 3)
转载自:《JavaScript模式》第六章