介绍
本文总结了ES3,ES5,ES7和NS(NonStandard)四种原型链继承的实现方法。
前言
ECMAScript 6 class将给开发者带来JavaScript OOP的规范实现,但这种方式的直接应用和普及至少得等到IE11被淘汰掉,而到那时,说不定我们已转向边沿领域了。
随着Web的快速发展,新的方法可能会随时取代旧的方法,而我们在lifetime中用过的方法,代表着一代人的记忆,又怎能忘怀?
分享
/**
* @method ES3Extends
* @param {Function} sub - subclass constrcutor
* @param {Function} sup - superclass constrcutor
* @return {Object} - original prototype of subclass constrcutor
*/
var ES3Extends=(function(){
// Object.keys polyfill
// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
var ObjectGetOwnPropertyNames=Object.getOwnPropertyNames||(function(){
var hasOwnProperty=Object.prototype.hasOwnProperty,
hasDontEnumBug=!({toString:null}).propertyIsEnumerable('toString'),
dontEnums=[
'toString','toLocaleString','valueOf',
'hasOwnProperty','isPrototypeOf','propertyIsEnumerable','constructor'
],
dontEnumsLength=dontEnums.length;
function keys(o) {
if (!(typeof o==='object'&&o!==null||typeof o==='function')){
throw new TypeError('Object.keys called on non-object');
}
var result,i;
result=[];
for(i in o) {
if(hasOwnProperty.call(o,i)){
result.push(i);
}
}
if(hasDontEnumBug){
for(i=0; i
另附上BDD测试
describe("4 methods to do prototype-chain extends",function(){
var List=null;
beforeEach(function(){
List=function List(){};
});
describe("ES3Extends",function(){
it("should set prototype of List.prototype to Array.prototype",function(){
ES3Extends(List,Array);
expect(List.prototype.push).toBe(Array.prototype.push);
});
});
describe("ES5Extends",function(){
it("should set prototype of List.prototype to Array.prototype",function(){
ES5Extends(List,Array);
expect(Object.getPrototypeOf(List.prototype)).toBe(Array.prototype);
});
});
xdescribe("ES7Extends",function(){
it("should set prototype of List.prototype to Array.prototype",function(){
ES7Extends(List,Array);
expect(Object.getPrototypeOf(List.prototype)).toBe(Array.prototype);
});
});
describe("NSExtends",function(){
it("should set prototype of List.prototype to Array.prototype",function(){
NSExtends(List,Array);
expect(Object.getPrototypeOf(List.prototype)).toBe(Array.prototype);
});
});
});
这其中:
- 较新的JavaScript运行环境能兼容旧的继承方法,反之则不行。
- NS方法的效率理论上比其他方法要高,但需进行特性检测,仅当环境支持所需特性时才能采用此方法。
参考
[2]
v8 ArrayForEach