關於JavaScript繼承,方式很多,包括compile-to-javascript的語言TypeScript, CoffeeScript以及網站MDN, GitHub, Modernizr各種polyfill都給出了穩妥的實現方案。
從ES5的角度看,這其中一些方案在功能上OK,但在語義上卻不盡如人意。
本人從這些方案中採取一些比較潮的思路,整理出一份方案,可實現與原生DOM類繼承的風格一致,達到功能和語義兼得的效果(當然,就別再老想著99後ES3了)。
如果你的WebApp是基於ES5運行環境的,可以評估或fork此方案。
//exports Function.prototype.extends//exports global.getPrototypeNames//基於ES5的繼承實現函數Function.prototype.extends=(function(){function getOwnPropertyDescriptors(object){return Object.getOwnPropertyNames(object).reduce(function(pds,pn){return pds[pn]=Object.getOwnPropertyDescriptor(object,pn),pds;},{});}/** * 繼承一個類。 * 若有後續類,則共用後續類截至到當前的快照屬性(constructor除外), * 這些屬性中的getters,setters和methods須考慮到要是通用的(如Array的那些methods) **/function inherits(s){var c,p;c=this;if(typeof s==="function"){p=Object.create(s.prototype,getOwnPropertyDescriptors(c.prototype));}else{p=c.prototype;}if(arguments.length>1){Array.prototype.slice.call(arguments,1).forEach(function(s){var pds=getOwnPropertyDescriptors(s.prototype);delete pds.constructor;Object.defineProperties(p,pds);});}c.prototype=p;}return inherits;}());//測試準備//~~~~~~~~~~~~~~~~~~~~~~~~// BaseList extends Array//~~~~~~~~~~~~~~~~~~~~~~~~function BaseList(){this.length=this.length;}BaseList.prototype.add=function(e){return this.push(e);};BaseList.extends(Array);//~~~~~~~~~~~~~~~~~~~~~~~~// ItemList extends BaseList//~~~~~~~~~~~~~~~~~~~~~~~~function ItemList(){BaseList.call(this);}ItemList.extends(BaseList,EventTarget);ItemList.prototype.item=function item(index){index>>>=0;return index "));list.push(document.documentElement);list.push(document.head);console.assert(list.item(1)===document.head,"The second item of list is document.head");