说到Javascript的继承,相信只要是前端开发者都有所了解或应用,因为这是太基础的知识了。但不知各位有没有深入去理解其中的玄机与奥秘。今本人不才,但也想用自己的理解来说一说这其中的玄机和奥秘。

一、类继承的发展吏

  • function实现的继承

function的继承是完全模仿了OOP的编程思想。实现的是类的继承

  • object.create实现的继承

用object.create来修改其原型

  • es6的继承

增加了class来模拟OOP的继承实现。上述两种继承实现,他都还是支持的。

二、各时期类继承的实现

  • function继承方式的实现(OOP)
function Animate(name){
this.name = name;
}
Animate.prototype.getName = function(){
return this.name;
} function Dog(name){
Animate.apply(this,arguments);
this.leg = 4;
}
Dog.prototype = Inherit(Animate, Dog);
Dog.prototype.say = function(){
return 'wang';
} //function模式的继承
function Inherit(parent, child){
//创建一个无原型方法的类
function f(){}
f.prototype = parent.prototype; //将父对象的原型赋给临时对象
f.prototype.constructor = child; //将子类构造函数绑定到 临时对象的 prototype原型上,保持子类构造函数与prototype上的一致。
return new f(); //执行了f的构造函数,而没有执行prototype.constructor指向的构造函数
} var dog = new Dog('dog');
console.log('getName:' + dog.getName()); //dog
console.log("say:" + dog.say()); //wang
console.log( 'dog instanceof Animate:' + (dog instanceof Animate)); //true
console.log( 'dog instanceof Animate: ' + (dog instanceof Dog)); //true

OOP方式的继承实现网上有很多种,如:原型链,实现、组合、寄生组合继承等。上述实现为寄生组合继承在,算比较通用且完美的一种方案了。

  • object.create实现继承
    这是一个升级版本的类式继承,需要了解object.create方法。Object.create(proto, [propertiesObject]),其中proto是新创建对象的原型对象,而propertiesObject是可选的,要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是原型链接上的属性)。
    我们还需要了解的方法:Object.setPrototypeOf(内部原型的写方法);Object.getPrototypeOf(内部原型的读方法)。内部原型:[[prototype]] == proto
    上述继承代码的改造后
function Animate(name){
this.name = name;
}
Animate.prototype.getName = function(){
return this.name;
} function Dog(name){
Animate.apply(this,arguments);
this.leg = 4;
}
Inherit(Animate, Dog); //调用点改造
Dog.prototype.say = function(){
return 'wang';
}
//继承实现方法改造
function Inherit(parent, child){
child.prototype = Object.create(parent.prototype); //create实现parent上的原型复制
child.prototype.constructor = child; //将构造函数指回子类
} var dog = new Dog('dog');
console.log('getName:' + dog.getName()); //dog
console.log("say:" + dog.say()); //wang
console.log( 'dog instanceof Animate:' + (dog instanceof Animate)); //true
console.log( 'dog instanceof Animate: ' + (dog instanceof Dog)); //true

2.1 对prototype的尝试

上述示例中用了Object.create方法创建一个对象,然后再赋值给Prototype,而为什么不用Object.setPrototypeOf方法直接改变其Prototype的值呢。原因摘录来源于MDN:

由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]在各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.proto = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。

对象继承的实现:

var animate = {
name: "name"
};
Object.setPrototypeOf(animate,{
getName: function(){
return this.name;
}
}); var dog = {
leg: 4
};
Object.setPrototypeOf(dog,{
say: function(){
return 'wang';
}
});
Object.setPrototypeOf(Object.getPrototypeOf(dog),Object.getPrototypeOf(animate)); console.log('getName:' + dog.getName()); //dog
console.log("say:" + dog.say()); //wang

三、ES6类继承的实现

es6对类继承提供了原生的支持,这让Javascript更像后端语言了,简单使用如下:

class Animate{
constructor(name){
this.name = name
}
getName(){
return this.name;
}
} class Dog extends Animate{
constructor(name){
super(name);
this.leg = 4;
}
say(){
return "wang";
}
}
var dog = new Dog('dog');
console.log('getName:' + dog.getName()); //dog
console.log("say:" + dog.say()); //wang
console.log( 'dog instanceof Animate:' + (dog instanceof Animate)); //true
console.log( 'dog instanceof Animate: ' + (dog instanceof Dog)); //true

四、总结及疑问

经过本文梳理,你是否发现Javascript的类继承实现越来越简单,更接近于Java,.net这类静态编译语言了,或许这就是所谓的万物归一的哲学道理。但在此还是存在一个极大的疑问:Object.setPrototypeOf方法在MDN不建议使用,说是更改内部的[[prototype]]属性存在性能问题 和 影响。不知道其影响为何,望大神们指定

Javascript继承,再谈的更多相关文章

  1. JavaScript之再谈回调与闭包

    前些阵子写了几篇关于回调和闭包的博文,感觉自己都是似懂非懂,最近在项目中又碰到了类似的情况,故在此咱们来重弹js中的回调与闭包. 先说说回调: 百度百科: 回调函数就是一个通过函数指针调用的函数.如果 ...

  2. JavaScript:再谈Tasks和Microtasks

    JavaScript是单线程,也就是说JS的堆栈中只允许有一类任务在执行,不可以同时执行多类任务.在读js文件时,所有的同步任务是一条task,当然了,每一条task都是一个队列,按顺序执行.而如果在 ...

  3. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  4. 再谈javascriptjs原型与原型链及继承相关问题

    什么是原型语言 只有对象,没有类;对象继承对象,而不是类继承类. “原型对象”是核心概念.原型对象是新对象的模板,它将自身的属性共享给新对象.一个对象不但可以享有自己创建时和运行时定义的属性,而且可以 ...

  5. 再谈JavaScript的数据类型问题

    JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...

  6. lesson 4 再谈继承多态,抽象类和接口

    再谈多态,抽象类和接口 上一次博客已经概念性的概述了继承多态,抽象类和接口,这次来具体的谈一谈他们之间的联系和需要注意的地方. 一.继承和多态:Inheritance (继承) & Polym ...

  7. Java继承之再谈构造器

    目录 Java继承之再谈构造器 初始化基类 默认构造器 带参数的构造器 子类调用父类构造器 Java继承之再谈构造器 初始化基类 前面提到,继承是子类对父类的拓展.<Thinking in Ja ...

  8. 浅谈javascript继承体系

    最近做web项目,接触了jquery等框架,虽然使用方便,但是还是想学习下Javascript,今天分享下最近对js原型继承的理解,不足之处欢迎指正. 一.构造器的原型属性与原型对象 刚接触js时通常 ...

  9. 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

    这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理汇总.如果对文中的题目全部了然于胸,觉得对整个angular框架应该掌握的七七八八了.希望志同道合的通知补充 ...

  10. 再谈js对象数据结构底层实现原理-object array map set

    如果有java基础的同学,可以回顾下<再谈Java数据结构—分析底层实现与应用注意事项>:java把内存分两种:一种是栈内存,另一种是堆内存.基本类型(即int,short,long,by ...

随机推荐

  1. 使用Gradle发布SNAPSHOT版本到JCenter(oss.jfrog.org)

    回顾历史 发布SNAPSHOT版本的问题 解决问题 完整脚本 使用方法 本文原创. 转载请注明CSDN博客出处: http://blog.csdn.net/maosidiaoxian/article/ ...

  2. 如何使用ZOL一键安装器下载中关村在线的源安装包

    如何使用ZOL一键安装器下载中关村在线的源安装包 马根峰               (广东联合电子服务股份有限公司, 广州 510300) 摘要    中关村在线最近开始推出ZOL一键安装器,用户直 ...

  3. Linux内核中断和异常分析(下)

    这节,我们继续上,中(以前的日志有)篇目进行分析,结合一个真实的驱动案例来描述linux内核中驱动的中断机制,首先我们先了解一下linux内核中提供的中断接口. 这个接口我们需要包含一个头文件:#in ...

  4. 和菜鸟一起学linux之linux性能分析工具oprofile移植

    一.内核编译选项 make menuconfig General setup---> [*] Profiling support <*> OProfile system profil ...

  5. mac os X中关于dayone缓存的实际文件位置

    最近刚安装了mac版的dayone软件,感觉蛮不错的!以前一直用iphone版的,mac版是要米的,68米丫!想了想还是一咬牙:买了! 我用的是iCloud同步,虽然资料放在云中,但本地还是会有缓存的 ...

  6. eclipse中英文(等各国语言)版本转换发放

    eclipse界面语言的切换方法 1.该方法只支持安装过中文包的eclipse(其实中文包中几乎包含了全世界所有的语言,只是调用了其中的中文简体而已) 2.在桌面的快捷方式中目标的地址后面加上参数-n ...

  7. spring mvc和spring的区别

    springmvc只是spring其中的一部分. spring 可以 支持 hibernate ,ibatis ,JMS,JDBC 支持事务管理, 注解功能,表达式语言,测试 springmvc 就是 ...

  8. 前端技术之_CSS详解第六天--完结

    前端技术之_CSS详解第六天--完结 一.复习第五天的知识 a标签的伪类4个: a:link 没有被点击过的链接 a:visited 访问过的链接 a:hover 悬停 a:active 按下鼠标不松 ...

  9. HTML学习笔记 day two

    HTML学习笔记 day two Charter three网站中的文本样式标签 3.1设置标题字体 语法结构:<h#>标题文字</h#> 注:其中的#可以为1,2,3,4,5 ...

  10. JavaScript函数节流和函数防抖之间的区别

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...