都0202年了,你还不知道javascript有几种继承方式?
// 父类构造函数
function Parent(color) {
this.color = color;
this.print = function() {
console.log(this.color);
}
}
现在要编写一个子类函数来继承这个父类,如下:
// 子类构造函数
function Son(color) {
Parent.call(this, color);
}
上面代码可以看到,子类Son是通过Parent.call的方式去调用父类构造函数,然后把this对象传进去,执行父类构造函数之后,子类Son就拥有了父类定义的color和print方法。
调用一下该方法,输出如下:
// 测试
var son1 = new Son('red');
son1.print(); // red
var son2 = new Son('blue');
son2.print(); // blue
function Flower() {
this.colors = ['黄色', '红色'];
this.print = function () {
console.log(this.colors)
}
}
function Rose() {
Flower.call(this);
}
var r1 = new Rose();
var r2 = new Rose();
console.log(r1.print()); // [ '黄色', '红色' ]
console.log(r2.print()); // [ '黄色', '红色' ]
我们现在有一个基类Flower,它有一个属性colors,现在我们把某一个实例的colors值改一下:
r1.colors.push('紫色');
console.log(r1.print()); // [ '黄色', '红色', '紫色' ]
console.log(r2.print()); // [ '黄色', '红色' ]
- 优点:所有的基本属性独立,不会被其他实例所影响;
- 缺点:所有希望共享的方法和属性也独立了,没有办法通过修改父类某一处来达到所有子实例同时更新的效果;同时,每次创建子类都会调用父类构造函数一次,所以每个子实例都拷贝了一份父类函数的内容,如果父类很大的话会影响性能;
function Parent() {
this.color = 'red';
this.print = function() {
console.log(this.color);
}
}
function Son() {
}
我们有一个父类和一个空的子类;
Son.prototype = new Parent();
Son.prototype.constructor = Son;
接着我们把子函数的原型属性赋值给了父函数的实例;
var son1 = new Son();
son1.print(); // red
Son.prototype = new Parent();
Son.prototype.constructor = Son;
function Flower() {
this.colors = ['黄色', '红色'];
this.print = function () {
console.log(this.colors)
}
}
function Rose() {}
Rose.prototype = new Flower();
Rose.prototype.constructor = Rose;
var r1 = new Rose();
var r2 = new Rose();
console.log(r1.print()); // [ '黄色', '红色' ]
console.log(r1.print()); // [ '黄色', '红色' ]
r1.colors.push('紫色');
console.log(r1.print()); // [ '黄色', '红色', '紫色' ]
console.log(r2.print()); // [ '黄色', '红色', '紫色' ]
- 优点:很好的实现了方法的共享;
- 缺点:正是因为什么都共享了,所以导致一切的属性都是共享的,只要某一个实例进行修改,那么所有的属性都会变化
function Parent(color) {
this.color = color;
}
Parent.prototype.print = function() {
console.log(this.color);
}
function Son(color) {
Parent.call(this, color);
}
Son.prototype = new Parent();
Son.prototype.constructor = Son;
var son1 = new Son('red');
son1.print(); // red
var son2 = new Son('blue');
son2.print(); // blue
var obj = {
color: 'red',
print: function() {
console.log(this.color);
}
};
var son1 = Object.create(obj);
son1.print(); // red
var son2 = Object.create(obj);
son2.print(); // red
寄生式继承本质上还是原型链继承,Object.create(obj);方法意思是以obj为原型构造对象,所以寄生式继承不需要构造函数,但是同样有着原型链继承的优缺点,也就是它把所有的属性和方法都共享了。
function Parent(color) {
this.color = color;
}
Parent.prototype.print = function() {
console.log(this.color);
}
function Son(color) {
Parent.call(this, color);
}
Son.prototype = Object.create(Parent.prototype);
Son.prototype.constructor = Son;
var son1 = new Son('red');
son1.print(); // red
var son2 = new Son('blue');
son2.print(); // blue
都0202年了,你还不知道javascript有几种继承方式?的更多相关文章
- JavaScript的3种继承方式
JavaScript的继承方式有多种,这里列举3种,分别是原型继承.类继承以及混合继承. 1.原型继承 优点:既继承了父类的模板,又继承了父类的原型对象: 缺点:不是子类实例传参,而是需要通过父类实例 ...
- Javascript的四种继承方式
在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...
- JavaScript的几种继承方式
看<JavaScript高级程序设计>做的一些笔记 ECMAScript只支持实现继承,不支持接口继承(因为函数没有签名) 原型链(实现继承的主要方法): function SuperTy ...
- JavaScript之四种继承方式讲解
在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...
- JavaScript 常见的六种继承方式
JavaScript 常见的六种继承方式 前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分 ...
- JavaScript的7种继承模式
<JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...
- 【转】SVG与HTML、JavaScript的三种调用方式
原文:https://www.cnblogs.com/guohu/p/5085045.html SVG与HTML.JavaScript的三种调用方式 一.在HTMl中访问SVG的DOM 1 2 3 4 ...
- JavaScript中七种函数调用方式及对应 this 的含义
this 在 JavaScript 开发中占有相当重要的地位,不过很多人对this这个东西都感觉到琢磨不透.要真正理解JavaScript的函数机制,就非常有必要搞清楚this到底是怎么回事. 函数调 ...
- JavaScript常用八种继承方案
更新:在常用七种继承方案的基础之上增加了ES6的类继承,所以现在变成八种啦,欢迎加高级前端进阶群一起学习(文末). --- 2018.10.30 1.原型链继承 构造函数.原型和实例之间的关系:每个构 ...
随机推荐
- ES6新增的 Set 和 WeakSet 是什么玩意?在此揭晓
现在的章节内容会更加的紧密,如果大家看不懂可以先去看以前的文章,当然看了的忘了,也可以去看一下,这样学习后面的内容才会更加容易. 什么是Set结构 Set是ES6给开发者带来的一种新的数据结构,你可以 ...
- SQLI-LABS学习笔记(四)
第十六关 和之前的关卡一样,修改闭合,无意义的关卡 ")闭合即可 第十七关 这题从源码上看发现 这里进行了两次查询 先查询了用户名是否存在 再查询密码是否匹配 ...
- mysql面试(1)
一一个 SQL 执行行行的很慢,我们要分两种情况讨论:1.大大多数情况下很正常,偶尔很慢,则有如下原因(1).数据库在刷新脏⻚页,例例如 redo log 写满了了需要同步到磁盘.(2).执行行行的时 ...
- Inno Setup [Run] Section 双引号嵌套
https://stackoverflow.com/questions/26257808/inno-setup-how-to-run-a-code-procedure-in-run-section-o ...
- ThinkJS前端搭配vue时的Nginx配置
Thinkjs 作为奇舞团开源的nodejs mvc框架之一,引起了很多NodeJS程序员的亲赖.但是其关于静态文件处理部分支持不够完善,主要是体现在SPA单页应用,之前在ThinkJS 2.*版本时 ...
- opencv-2-VS2017与QT显示图像
opencv-2-VS2017与QT显示图像 opencvqtVSC++ 目的 使用 VS 构建第一个 opencv 程序 使用 QT 构建 第一个 opencv 程序 VS 导入 QT 程序 开始 ...
- CSS样式1
编写CSS样式: 1.标签的style属性 如:<div style="width:980px;"></div> 2.写在head里面,style标签中写样 ...
- 为什么LIKELY和UNLIKELY要用两个叹号
LIKELY和UNLIKELY的一般定义如下: #define LIKELY(x) (__builtin_expect(!!(x),1))#define UNLIKELY(x) (__builtin_ ...
- Bogon
Definition - What does Bogon mean? A bogon is an bogus IP address from the bogon space, which is a s ...
- element UI排坑记(一):判断tabs组件是否切换
之所以将这个问题列在排坑记之中,是因为官方组件的一个属性颇有些隐蔽,这个问题曾经折腾了本人较多时间,始终思维固着,且使用搜索引擎也不容易搜索到答案,故记之.然而实际解决却是相当简单的. 一.问题描述 ...