zoukankan      html  css  js  c++  java
  • 一种基于ES5的JavaScript继承

    关于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<this.length?this[index]:null;
    };
    
    //~~~~~~~~~~~~~~~~~~~~~~~~
    // ElementList extends ItemList
    //~~~~~~~~~~~~~~~~~~~~~~~~
    function ElementList(){
    	ItemList.call(this);
    }
    ElementList.extends(ItemList);
    ElementList.prototype.namedItem=function namedItem(name){
    	var index=this.findIndex(function(elem){return elem.name===name;});
    	return index===-1?null:this[index];
    };
    
    
    //測试工具函数之获取原型链名单
    var getPrototypeNames=(function(){
    	function typeOf(value){
    		return Object.prototype.toString.call(value).slice(8,-1);
    	}
    	function isObject(value){
    		return typeof value==="object"&&value!==null||typeof value==="function"
    	}
    	function constructorNameOf(proto){
    		return typeof proto.constructor==="function"?proto.constructor.name:typeOf(proto)
    	}
    	function getPrototypeNames(object){
    		var names,proto;
    		names=[];
    		proto=Object.getPrototypeOf(object);
    		while(isObject(proto)){
    			names.push(constructorNameOf(proto));
    			proto=Object.getPrototypeOf(proto)
    		}
    		return names;
    	}
    	return getPrototypeNames;
    }());
    
    
    
    //运行測试
    var list=new ElementList();
    
    console.dir(list);
    console.log("list: "+getPrototypeNames(list).join(" > "));
    
    list.push(document.documentElement);
    list.push(document.head);
    console.assert(list.item(1)===document.head,"The second item of list is document.head");
    
    

  • 相关阅读:
    一维数组的 K-Means 聚类算法理解
    c#计算2个字符串的相似度
    一个人开发的html整站源码分享网站就这么上线了
    html页面显示服务器时间
    禁用浏览器自动填充表单解决办法
    布隆过滤器
    (转)二进制与三进制趣题
    随机算法_模拟退火算法
    NAT穿越
    (转)为什么所有浏览器的userAgent都带Mozilla
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/3766136.html
Copyright © 2011-2022 走看看