介紹
本文總結了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方法的效率理論上比其他方法要高,但需進行特性檢測,僅當環境支持所需特性時才能採用此方法。