JS的6种常见继承模式
2024-10-14 12:06:54
数天前在知乎看到有人阿里面试被问到这个问题,我来总结一下。
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);
这个没什么缺点,主要是写着稍微麻烦一点。
最新文章
- apt-get程序和系统管理
- JavaScript 在函数中使用Ajax获取的值作为函数的返回值
- js基础第3天
- ArrayList与Vector、HashMap与HashTable
- SqlServer SSAS IIS 部署
- 获取当前url并指定url中的字符 效果
- zrender源码分析1:总体结构
- Java自学手记——注解
- 【转】 awk 学习笔记
- python selenium-webdriver 等待时间(七)
- JSF初学之概念篇1
- Timestamp 数据类型四舍五入引起的神奇bug
- redis 安装配置 [转]
- day75
- StringIO-将字符串当做文件处理
- Codeforces Round #290 (Div. 2) 拓扑排序
- mongod 一些命令汇总
- GIS专业书籍、文档、数据、网站、工具等干货
- 【POJ】2942 Knights of the Round Table(双连通分量)
- 谈pkusc2016的几道数学题
热门文章
- 阿里云SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
- PHP获取中文首字母的函数
- 《算法》第五章部分程序 part 8
- 《GPU高性能编程CUDA实战》第六章 常量内存
- Android dialog使用
- E2040 Declaration terminated incorrectly - System.ZLib.hpp(310) ZLIB_VERSION
- 正则表达式——WPF输入控件TextBox 限定输入特定字符
- rocketmq 4.2.0 版本 控制台本地搭建(史上最简单教程)
- ReactiveX 学习笔记(3)转换数据流
- LeetCode OJ 215. Kth Largest Element in an Array