关于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继承的更多相关文章

  1. JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)

    JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...

  2. javascript继承的三种模式

    javascript继承一般有三种模式:组合继承,原型式继承和寄生式继承: 1组合继承:javascript最为广泛的继承方式通过原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承,同 ...

  3. javascript继承(五)—prototype最优两种继承(空函数和循环拷贝)

    一.利用空函数实现继承 参考了文章javascript继承—prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...

  4. javascript继承—prototype最优两种继承(空函数和循环拷贝)

    一.利用空函数实现继承 参考了文章javascript继承-prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...

  5. javaScript继承的几种实现方式?

    js继承总共分成5种,包括构造函数式继承.原型链式继承.组合式继承.寄生式继承和寄生组合式继承. 构造函数式继承 首先来看第一种,构造函数式继承,顾名思义,也就是利用函数去实现继承:构造函数继承,使用 ...

  6. javascript继承之学习笔记

    今天记录一下学习javascript的继承. 继承基本上是基于“类”来说的,而javascript中并不存在真正的类,所以就出现了各种模拟“类”的行为,然后就堂而皇之的使用起了类的概念.这里不谈“类” ...

  7. JavaScript 继承小记

    面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过“类”(class) ...

  8. 一篇文章图文并茂地带你轻松学完 JavaScript 继承

    JavaScript 继承 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 继承种类 简单的继承种类可以分为 构造函数继承 原型链继承 clas ...

  9. 关于JavaScript继承的那些事

    在JavaScript中,对象的创建可以脱离类型(class free),通过字面量的方式可以很方便的创建出自定义对象. 另外,JavaScript中拥有原型这个强大的概念,当对象进行属性查找的时候, ...

随机推荐

  1. element-ui 2.7.2版本使用 表格展开行 功能遇到的奇葩问题?

    在使用 element-ui 2.7.2版本的时候报下面的错误: [Vue warn]: Error in callback for watcher "data": "E ...

  2. Visual Studio Code 常用插件整理

    常用插件说明: 一.HTML Snippets 超级使用且初级的H5代码片段以及提示 二.HTML CSS Support  让HTML标签上写class智能提示当前项目所支持的样式 三.Debugg ...

  3. java8 - 5

    import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.Lis ...

  4. USACO 6.3 Cowcycles

    CowcyclesOriginally by Don Gillies [International readers should note that some words are puns on co ...

  5. 20169211 《Linux内核原理与分析》第十一周作业

    SET-UID程序漏洞实验 一.实验简介 Set-UID 是Unix系统中的一个重要的安全机制.当一个Set-UID程序运行的时候,它被假设为具有拥有者的权限.例如,如果程序的拥有者是root,那么任 ...

  6. redis在Linux下的远程连接

    1.redis在Linux下的远程连接: $ redis-cli -h host -p port -a password 如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass ...

  7. 基于五阶段流水线的RISC-V CPU模拟器实现

    RISC-V是源自Berkeley的开源体系结构和指令集标准.这个模拟器实现的是RISC-V Specification 2.2中所规定RV64I指令集,基于标准的五阶段流水线,并且实现了分支预测模块 ...

  8. JDK源码分析(四)——LinkedHashMap

    目录 LinkedHashMap概述 内部字段及构造方法 存储元素 取出元素 删除元素 迭代器 利用LinkedHashMap简单实现LRU算法 总结 LinkedHashMap概述   JDK对Li ...

  9. Error after SQL Server 2012 installation: Login Failure for "SQL Server Integration Services 11.0" SSIS service

    When you install SQL Server 2012 and you try to connect to SSIS services, you cannot due to that the ...

  10. iOS 9应用开发教程之多行读写文本ios9文本视图

    iOS 9应用开发教程之多行读写文本ios9文本视图 多行读写文本——ios9文本视图 文本视图也是输入控件,与文本框不同的是,文本视图可以让用户输入多行,如图2.23所示.在此图中字符串“说点什么吧 ...