数天前在知乎看到有人阿里面试被问到这个问题,我来总结一下。

1. 原型链继承:

 function SuperType() {
this.property = true;
} SuperType.prototype.getSuperProperty = function() {
return this.property;
}; function SubType() {} SubType.prototype = new SuperType(); var o = new Subtype(); console.log(o.getSuperProperty); // true

原型链的问题:子类所有对象的原型都是同一父类对象,如果我们修改到了原型对象,那么所有子类对象内容都会改变。

2. 借用构造函数(也称作伪造对象继承和经典继承):

借用构造函数是在子类中调用父类的构造函数(所谓借用)。

 function SuperType() {
this.property = ['hello', 'world'];
} function SubType() {
SuperType.call(this);
}

构造函数的问题:父类在原型链中定义的函数不能被子类访问,也就是说所有的函数都必须写在构造函数内部,无法复用。

3. 组合继承(伪经典继承)*:

将原型链继承和借用构造函数继承组合到一起。

 function SuperType(name) {
this.name = name;
this.color = ['red', 'green', 'blue'];
} SuperType.prototype.sayName = function() {
console.log(this.name);
}; function SubType(name) {
SuperType.call(this, name); // 第二次调用
} SubType.prototype = new SuperType(); // 第一次调用
SubType.prototype.constructor = Subtype; // 为了以后判断类型

不过组合继承也不是没有缺点,就是会至少调用两次构造函数,第一次调用在原型中添加了 SuperType 所拥有的属性,第二次调用的时候又覆盖了一次。这个开销其实是没有必要的。

4. 原型式继承:

 Ojbect.create(prototypeObj);

这个方法会创建一个新的对象,新的对象的原型是 prototypeObj。

缺点和原型继承一样。

5. 寄生式继承:

核心思想在于在函数内部增强对象,返回一个新对象。

 function createAnother(obj) {
var clone = Object.create(obj);
clone.sayHello = function() {
console.log('Hello');
};
return clone;
}

6. 寄生组合式继承:

完善组合式继承,不必为了指定子类型的原型而调用超类的构造函数,我们需要的无非就是超类的原型的一个副本(创造副本是为了子类上属性的修改不影响在原型链上的父类)而已,我们在一个函数里创建一个增强过的对象作为子类的原型(所谓寄生)。

 function SuperType(name) {
this.name = name;
} SuperType.prototype.sayName = function() {
console.log(this.name);
}; function SubType(name) {
Super.call(this, name);
} function inheritPrototype(subType, superType) {
var prototype = Object(superType.prototype);
// 如果不像上面这么写,那么在子类添加方法会影响到父类,这不合理。
prototype.constructor = subType;
subType.prototype = prototype;
} inheritPrototype(SubType, SuperType);

这个没什么缺点,主要是写着稍微麻烦一点。

JS的6种常见继承模式的更多相关文章

  1. JS中几种常见的数组算法(前端面试必看)

    JS中几种常见的数组算法 1.将稀疏数组变成不稀疏数组 /** * 稀疏数组 变为 不稀疏数组 * @params array arr 稀疏数组 * @return array 不稀疏的数组 */ f ...

  2. JS中5种经典继承方式

    继承 JS中继承的概念: 通过[某种方式]让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承 并不是所谓的xxx extends yyy 为什么要使用继承? 有些对象会有方法(动作 ...

  3. js+css:43种常见的浏览器兼容性问题大汇总

    javascript 1.HTML对象获取问题 FireFox:document.getElementById(“idName”); ie:document.idname或者document.getE ...

  4. VMware虚拟机中涉及的3种常见网络模式

    桥接模式.这种模式下,虚拟机和物理机连的是同一个网络,虚拟机和物理机是并列关系,地位是相当的.比如你家如果有用路由器,那么你的电脑和你的手机同时连接这个路由器提供的Wi-Fi,那么它们的关系就是这种模 ...

  5. JS中几种常见的高阶函数

    高阶函数:英文叫Higher-order function.JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数 ...

  6. js中几种常见的方法的实例 shift,unshift,push,prop

    1.shift()定义和用法 shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值. 语法:arrayObject.shift() 返回值:数组原来的第一个元素的值. 说明:如果 ...

  7. JavaScript 对象的创建和对6种继承模式的理解和遐想

      JS中总共有六种继承模式,包括原型链.借用构造函数.组合继承.原型式继承寄生式继承和寄生组合式继承.为了便于理解记忆,我遐想了一个过程,对6中模式进行了简单的阐述. 很长的一个故事,姑且起个名字叫 ...

  8. JS继承模式粗探

    之前提到了JS中比较简单的设计模式,在各种设计模式中被最常使用的工具之一就是原型链的继承.作为OOP的特质之一——继承,今天主要谈谈JS中比较简单的继承方法. 最基础的原型链继承在这里就不复述了,主要 ...

  9. JavaScript的7种继承模式

    <JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...

随机推荐

  1. hadoop的块

    http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html http://www.cnblogs.com/cloudma/articles/had ...

  2. IIS编辑器错误信息:CS0016解决方案

    错误信息: 运行asp.net程序时候,编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporar ...

  3. JQuery:聚焦清空输入框值,失焦恢复默认值

    本来这个小玩意很简单,不用记录到博客里,但今天是娱乐日,要快落一天,为了减轻负罪感,假装自己又学了点新东西 <!DOCTYPE html> <html> <head> ...

  4. leetcode44

    public boolean isMatch(String text, String pattern) { // 多一维的空间,因为求 dp[len - 1][j] 的时候需要知道 dp[len][j ...

  5. PHP 使用非对称加密算法(RSA)

    解释: 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey).公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密:如果用私有密 ...

  6. HTML学习-2标记标签-2

    三.表单元素 ①<form></form>表单标签,代表表单 主要属性:1.action提交到的页面.   2.method数据提交方式(get显示提交,有长度限制.post隐 ...

  7. python字符串的基本用法

    var1 = "hello word"var2 = "runootab"print var2.capitalize()#首字母大写print (var2.cou ...

  8. 尚硅谷redis学习6-持久化RDB

    是什么 持久化文件保存在dump.rdb中 持久化策略 在shutdown或flush或flushall后会立即持久化 重新启动后会从rdb文件中恢复数据 可以手动持久化 持久化失败时不允许写,如在强 ...

  9. NAT与FULL NAT的区别

    LVS 当前应用主要采用 DR 和 NAT 模式,但这 2 种模式要求 RealServer 和 LVS在同一个 vlan中,导致部署成本过高:TUNNEL 模式虽然可以跨 vlan,但RealSer ...

  10. Tcp连接的七次握手浅析

    LINUX 查看tcp连接数及状态 # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 8 ...