一种基于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");
一种基于ES5的JavaScript继承的更多相关文章
- JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)
JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...
- javascript继承的三种模式
javascript继承一般有三种模式:组合继承,原型式继承和寄生式继承: 1组合继承:javascript最为广泛的继承方式通过原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承,同 ...
- javascript继承(五)—prototype最优两种继承(空函数和循环拷贝)
一.利用空函数实现继承 参考了文章javascript继承—prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...
- javascript继承—prototype最优两种继承(空函数和循环拷贝)
一.利用空函数实现继承 参考了文章javascript继承-prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...
- javaScript继承的几种实现方式?
js继承总共分成5种,包括构造函数式继承.原型链式继承.组合式继承.寄生式继承和寄生组合式继承. 构造函数式继承 首先来看第一种,构造函数式继承,顾名思义,也就是利用函数去实现继承:构造函数继承,使用 ...
- javascript继承之学习笔记
今天记录一下学习javascript的继承. 继承基本上是基于“类”来说的,而javascript中并不存在真正的类,所以就出现了各种模拟“类”的行为,然后就堂而皇之的使用起了类的概念.这里不谈“类” ...
- JavaScript 继承小记
面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过“类”(class) ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 继承
JavaScript 继承 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 继承种类 简单的继承种类可以分为 构造函数继承 原型链继承 clas ...
- 关于JavaScript继承的那些事
在JavaScript中,对象的创建可以脱离类型(class free),通过字面量的方式可以很方便的创建出自定义对象. 另外,JavaScript中拥有原型这个强大的概念,当对象进行属性查找的时候, ...
随机推荐
- python中mock的使用
什么是mock? mock在翻译过来有模拟的意思.这里要介绍的mock是辅助单元测试的一个模块.它允许您用模拟对象替换您的系统的部分,并对它们已使用的方式进行断言. 在Python2.x 中 mock ...
- ssm使用Ajax的formData进行异步图片上传返回图片路径,并限制格式和大小
之前整理过SSM的文件上传,这次直接用代码了. 前台页面和js //form表单 <form id= "uploadForm" enctype="multipart ...
- C++拾遗——重新开始
http://www.cnblogs.com/uniqueliu/category/307731.html
- HBase(十)HBase性能调优总结
一. HBase的通用优化 1 高可用 在 HBase 中 Hmaster 负责监控 RegionServer 的生命周期,均衡 RegionServer 的负载,如果 Hmaster 挂掉了,那么整 ...
- Java 之 JDBC
mysql : //****** 四大金刚: 驱动类名.url.用户名.密码 //MySQL四大金刚 String driverClassname="com.mysql.jdbc.Drive ...
- 第一个web程序(ServletRequest , ServletResponse)
一.ServletRequest 1.获取参数的方法(四种) > String getParameter(String name): 根据请求参数的名字, 返回参数值. 若请求参数有多个值(例如 ...
- Xcode的快捷键及代码格式化
1. 文件CMD + N: 新文件 CMD + SHIFT + N: 新项目CMD + O: 打开 CMD + S: 保存 CMD+OPt+S:保存所有文件 CMD + SHIFT + S: 另存为 ...
- PHP程序员未来路在何方
PHP 从诞生到现在已经有20多年历史,从Web时代兴起到移动互联网退潮,互联网领域各种编程语言和技术层出不穷, Node.js . GO . Python 不断地在挑战 PHP 的地位.这些技术的推 ...
- 20169211 《Linux内核原理与分析》第十一周作业
SET-UID程序漏洞实验 一.实验简介 Set-UID 是Unix系统中的一个重要的安全机制.当一个Set-UID程序运行的时候,它被假设为具有拥有者的权限.例如,如果程序的拥有者是root,那么任 ...
- sort sign numeric
//JS001 EXEC PGM=SORT //* ...