js 中继承方式小谈
题外话
前段时间面试中笔试题有这道题目:
请实现一个继承链,要求如下:
构造函数
A():构造函数中有consoleA方法,可以实现console.log("a")
实例对象 a:a 可以调用consoleA方法构造函数
B():构造函数中有consoleB方法,可以实现console.log("b")
实例对象 b:b 可以调用consoleA和consoleB方法构造函数
C():构造函数中有consoleC方法,可以实现console.log("c")
实例对象 c:c 可以调用consoleA和consoleB和consoleB方法
ok,这个题目暂时搁置,再回到这个问题之前,我们先来看看 js 的继承方式
约定
// 父类
function Super() {
this.name = "parent0";
this.colors = ["red", "blue", "yellow"];
}
Super.prototype.sex = "男";
Super.prototype.say = function() {
console.log(" Oh,My God! ");
};
构造继承
原理
通过使用 call、apply 方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例
实现
function Sub() {
Super.call(this);
this.type = "sub";
}
var s = new Sub();
console.log(s.colors); //[ 'red', 'blue', 'yellow' ]
s.say(); //报错 sub.say is not a function
优缺点
- 优点:简单明了,直接继承超类构造函数的属性和方法
- 缺点:无法继承原型链上的属性和方法
原型链式继承(借用原型链实现继承)
实现
function Sub() {
this.type = "sub";
}
Sub.prototype = new Super();
var s1 = new Sub();
var s2 = new Sub();
sub1.colors.push("black");
console.log(s1.colors); //[ 'red', 'blue', 'yellow', 'black' ]
console.log(s2.colors); //[ 'red', 'blue', 'yellow', 'black' ]
sub1.say();
我们实例化了两个 Sub,在实例 s1 中为父类的 colors 属性 push 了一个颜色,但是 s2 也被跟着改变了。造成这种现象的原因就是原型链上中的原型对象它俩是共用的。这不是我们想要的,s1 和 s2 这个两个对象应该是隔离的,
组合继承
这里所谓的组合是指组合借用构造函数和原型链继承两种方式。
function Sub() {
Super.call(this);
this.type = "sub";
}
Sub.prototype = new Super();
var s1 = new Sub();
var s2 = new Sub();
s1.colors.push("black");
console.log(s1.colors); //[ 'red', 'blue', 'yellow', 'black' ]
console.log(s2.colors); //[ 'red', 'blue', 'yellow' ]
可以看到,s2和s1两个实例对象已经被隔离了,但这种方式仍有缺点。父类的构造函数被执行了两次,第一次是Sub.prototype = new Super(),第二次是在实例化的时候,这是没有必要的。那我们就继续优化吧!!
组合式继承优化1
function Sub(){
Super.call(this)
this.type = "sub";
}
Sub.prototype=Super.prototype
var s1=new Sub()
var s2=new Sub()
但是请看以下代码
console.log(s1.constructor.name);//Super
我们还可以用.constructor来观察对象是不是某个类的实例:从这里可以看到,s1的构造函数居然是父类Super,而不是子类sub,这显然不是我们想要的。
组合式继承优化2
function Sub(){
Super.call(this)
this.type = "sub";
}
Sub.prototype=Super.prototype
Sub.constructor=Sub
var s1=new Sub()
var s2=new Sub()
console.log(s1 instanceof Sub);//true
console.log(s1 instanceof Super);//true
console.log(s1.constructor.name);//Super
perfect!!
开题解答
回到开头的问题中来,
function A(){}
A.prototype.consoleA=function(){
console.log("a")
}
function B(){
A.call(this)
}
B.prototype.consoleB=function(){
console.log("b")
}
Object.assign(B.prototype,A.prototype)
function C(){
B.call(this)
}
C.prototype.consoleC=function(){
console.log("c")
}
Object.assign(C.prototype,B.prototype)
参考资料
前端面试必备之JS继承方式总结
大前端之路----JS继承的六种方式
js 中继承方式小谈的更多相关文章
- JS中继承方式总结
说在前面:为了使代码更为简洁方便理解, 本文中的代码均将"非核心实现"部分的代码移出. 一.原型链方式关于原型链,可点击<深入浅出,JS原型链的工作原理>,本文不再重复 ...
- js各种继承方式和优缺点的介绍
js各种继承方式和优缺点的介绍 作者: default 参考网址2 写在前面 本文讲解JavaScript各种继承方式和优缺点. 注意: 跟<JavaScript深入之创建对象>一样,更像 ...
- javascript中继承方式及优缺点(三)
文以<JavaScript高级程序设计>上的内容为骨架,补充了ES6 Class的相关内容,从我认为更容易理解的角度将继承这件事叙述出来,希望大家能有所收获. 1. 继承分类 先来个整体印 ...
- 浅谈js中继承的理解和实现
一.前言 java.C#等正统面向对象语言都会提供类似extend之类的处理类的继承的方法,而javascript并没有提供专门的方法用于继承,在javascript中使用继承需要一点技巧.js中实例 ...
- js中继承的几种用法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 <SPAN style="BACKGROUND-COLOR: #ffffff">& ...
- js中继承的方法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...
- js各种继承方式汇总
js中的各种继承实现汇总 首先定义一个父类: function Animal(name) { this.name = name || '动物' this.sleep = function () { c ...
- 谈谈JavaScript中继承方式
聊一聊js中的继承 一.简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型 父级构造函数 function Parent(param) { this.name = 'parent' ...
- js的继承方式分别适合哪些应用场景?
一.原型链 利用 Person.prototype = new Animal("Human") 实现继承: static式继承.能继承Animal.prototype.不可多重继承 ...
随机推荐
- Python自学:第四章 复制列表(1)
# -*- coding: GBK -*- my_foods = ['pizza', 'falafel', 'carrot cake'] friend_foods = my_foods[:] prin ...
- 打开桌面上的图标就会弹出"打开些文件可能会对您的计算机有害"解决方案
问题截图 方案步骤 运行 gpedit.msc 用户配置--管理模板--windows组件--附件管理器 找到中等危险文件类型抱含列表后右键-编辑 在指定中等风险扩展名中加入你文件的扩展名 应用, 确 ...
- Redis Desktop Manager可视化工具连接不上redis
1.在centos中启动redis之后,redis进程也是可查的,但是一连接可视化工具就报错: can't connect to redis-server 2.原因分析: ①首先redis是肯定已经开 ...
- MaxCompute表设计最佳实践
MaxCompute表设计最佳实践 产生大量小文件的操作 MaxCompute表的小文件会影响存储和计算性能,因此我们先介绍下什么样的操作会产生大量小文件,从 而在做表设计的时候考虑避开此类操作. 使 ...
- bzoj1293题解
[题意分析] 给你一条有n个点的数轴,每个点属于一个种类,总共有k个种类.求一段最短的线段,使对于每个种类,这段线段上有至少一个点属于它. [算法分析] 1.对于50%的数据,N≤10000 对于每一 ...
- 玩转gulp之watch监听文件自动编译
博客移至 https://www.dodoblog.cn/blog?id=5befc928e0feb34495b57035 我们在写页面的时候,用到sass less等css预处理器的时候,虽然写的很 ...
- idea和eclipse快捷键对比(转)
分类 功能点 Eclipse快捷键 IDEA快捷键 搜索 搜索文本 Ctrl + F Ctrl + F Ctrl + R 查找替换 Alt + P/A 逐个/全部替换 Alt + F3 查找当前选中词 ...
- sql中desc的妙用
很多情况下对表内部结构不熟悉,想看下我创建的表里面又多少表明,又想他按照首字母的规律排列, 这时候就要用desc +表名了. desc t_bike_info; hive> desc t_bik ...
- NetBeans简介和简单使用
1.什么是NetBeans? NetBeans IDE:可以使开发人员利用Java平台能够快速创建Web.企业.桌面以及移动的应用程序: 支持语言:PHP.Ruby.JavaScript.Groovy ...
- JAVA利用JXL导出 EXCEL (在原有的excel模板上把数据导到excel上)
添加依赖 <dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifactId>j ...