深入浅出js实现继承的7种方式
给大家介绍7中js继承的方法
有些人认为JavaScript并不是真正的面向对象语言,在经典的面向对象语言中,您可能倾向于定义类对象,然后您可以简单地定义哪些类继承哪些类(参考C++ inheritance里的一些简单的例子),JavaScript使用了另一套实现方式,继承的对象函数并不是通过复制而来,而是通过原型链继承
一、原型链继承
// 原型链实现继承
function Person(name,age) {
this.name=name;
this.age=age;
}
Person.prototype.show=function() {
console.log(`我是${this.name},我今年${this.age}`)
}
function Worker(name, age, job) {
Person.call(this, name, age);
this.job=job;
}
// 如果此处有Woker的原型对象上的方法,由于原型重定向,下面的代码会覆盖此方法
Worker.prototype = new Person();
// 应该写在此处
Worker.prototype.showJob=function() {
console.log(`我的工作是${this.job}`)
};
var mine = new Worker('佳', 18, '写代码');
console.log(mine);
mine.show();
mine.showJob();
二、借用构造函数继承
function Person(name, age){
this.name=name;
this.age=age;
}
function Worker(name, age, job){
Person.call(this, name, age);
this.job=job;
}
var mine=new Worker('佳', 18, '写代码的');
console.log(mine);
优点:1. 相对于原型链而言,借用构造函数有一个很大的优势,即可以在子类型构造函数中向父类型构造函数传递参数。
缺点:1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
三、组合继承(组合原型链继承和借用构造函数继承)(常用)
// 组合继承
function Person(name,age) {
this.name=name;
this.age=age;
}
Person.prototype.show=function() {
console.log(`我是${this.name},我今年${this.age}`)
}
function Worker(name, age, job) {
Person.call(this, name, age);
this.job=job;
}
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;
Worker.prototype.showJob=function (){
console.log(`我的工作是${this.job}`)
};
var mine = new Worker('佳', 18, '打杂的');
console.log(mine);
mine.show();
mine.showJob();
重点:结合了两种模式的优点,传参和复用
优点:1、可以继承父类原型上的属性,可以传参,可复用。
2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
四、原型式继承
// 原型式继承
function Woker(o){
function Empty(){};
Empty.prototype = o;
return new Empty();
}
var mine = {
name: 'jia',
age: 18,
job: '打杂的'
};
var anotherMine =Woker(mine);
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:1、所有实例都会继承原型上的属性。
2、无法实现复用。(新实例属性都是后面添加的)
var woker={
name: 'jia',
age: 18,
job: '打杂的'
}
var mine = Object.create(woker);
原理和上面相同,ECMAScript 5 通过新增 Object.create()方法规范化了原型式继承。
// 寄生式继承
function createAnother(o) {
var person = Woker(o);
person.show=function() {
console.log(`我是jia`)
}
return person;
}
var mine = {
name: 'jia',
age: 18,
job: '打杂的'
};
var anotherMine = createAnother(mine);
重点:就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用。
也可用 Object.create()方法实现
六、寄生组合式继承
//寄生组合式继承
function inheritProto(parents,child){
var o=Object.create(parents.prototype);
o.constructor=child;
child.prototype=o;
}
//父类构造函数
function Parents(surname){
this.surname=surname;
}
Parents.prototype.getSurname=function(){
console.log(this.surname);
}
//子类构造函数
function Child(surname,age){
Parents.call(this,surname);
this.age=age;
}
inheritProto(Parents,Child); Child.prototype.getAge=function(){
console.log(this.age);
}
寄生组合式继承,集寄生式继承和组合继承的优点与一身,是实现基于类型继承的最有效方式。YUI 的 YAHOO.lang.extend()方法采用了寄生组合继承,从而让这种模式首次 出现在了一个应用非常广泛的 JavaScript 库中。要了解有关 YUI 的更多信息,请访问 http://developer. yahoo.com/yui/。
七、ES6的Class实现继承
class Person{
constructor(name, age){
this.name=name;
this.age=age;
}
show(){
alert(this.name);
alert(this.age);
}
}
class Worker extends Person{
constructor(name, age, job){
super(name, age);
this.job=job;
}
showJob(){
alert(this.job);
}
}
let me=new Worker('jia', 18, '前端攻城狮');
me.show();
me.showJob();
好啦,常见的7种JS继承的方法介绍完了。~~
深入浅出js实现继承的7种方式的更多相关文章
- js实现继承的5种方式 (笔记)
js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...
- js 实现继承的几种方式
//js中实现继承的几种方式 //实现继承首先要有一个父类,先创造一个动物的父类 function Animal(name){ this.name = name; this.shoot = funct ...
- js 实现继承的6种方式(逐渐优化)
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- js实现继承的两种方式
这是面试时面试官会经常问到问题: js的继承方式大致可分为两种:对象冒充和原型方式: 一.先说对象冒充,又可分为3种:临时属性方式.call().apply(): 1.临时属性方式: 当构造对象son ...
- js实现继承的5种方式
js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式1.使用对象冒充实现继承(该种实现 ...
- JS实现继承的几种方式
前言 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一.那么如何在JS中实现继承呢?让我们拭目以待. JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如下: // 定义一个 ...
- JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式
前 言 JRedu 在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 . 成员属性.静态属性.原型属性与JS原型链).今天 ...
- JS 面向对象 ~ 继承的7种方式
前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...
- JS实现继承的几种方式(转)
转自:幻天芒的博客 前言 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一.那么如何在JS中实现继承呢?让我们拭目以待. JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如 ...
随机推荐
- 【已解决】前端到后端400错误(The server cannot or will not process the request due to...)
看到400错误,一般是请求无效.出现该异常一般有三种情况: 第一种情况: 前端提交的内容在后端一般都用String类型来接收,用Date类型接收会报错. 第二种情况: 在提交表单的时候,填写的数据类型 ...
- layui省市区三级联动城市选择
基于layui框架制作精美的省市区下拉框三级联动菜单选择, 支持三级联动城市选择,点击提交获取选中值代码. 示例图如下: 资源链接: https://pan.baidu.com/s/1s6l8iDBE ...
- Last 2 dimensions of the array must be square
这个报错是因为我们在求解行列式的值的时候使用了: np.linalg.det(D) 但是D必须是方阵才可以进行运算,不是方阵则会报错,我们把之前的行列式更改为方阵就不会再报错了,当然这也是numpy自 ...
- form-data、x-www-form-urlencoded、raw、binary的区别(非原创)
文章大纲 一.form-data介绍二.x-www-form-urlencoded介绍三.raw介绍四.binary介绍五.参考文章 一.form-data介绍 http请求中的multipart/f ...
- bay——RAC 表空间时数据文件误放置到本地文件系统-介质恢复.txt
RAC添加新表空间时数据文件误放置到本地文件系统的修正 于是我想11G 也兼容这些操作的方法,但是11G的新特性有一点就是可以直接支持ASM文件系统直接可以和本地文件系统进行文件的拷贝了,也就是有三种 ...
- Druid-代码段-1-2
所属文章:池化技术(一)Druid是如何管理数据库连接的? 本代码段对应流程1.1,责任链的执行: //DruidDataSource类里的方法:获取连接 public DruidPooledConn ...
- 你的学习方法怎么样?IT的学习方法应该是什么-Dotest
OK,自从你打开这个文章,那么一定跟我有类似的困惑. 建议1)IT的东西没有背诵的,要做.要做,一定要动手做: 2)讨论.讨论,一定要多讨论.在讨论过程中,以往的不理解问题,可能就迎刃而解了: 3)知 ...
- arp心得-caidachun
arp地址解析协议,以前也学习过,一直有疑问,不同网段怎么解析,arp代理是什么,静态路由为什么可以配置下一跳是接口,而不是ip 1.同网段广播请求,单播应答 2.不同网络根据路由表的下一跳地址ip地 ...
- 利用Github建立博客专用图库
0.前言 当我们写博客或者文档的时候常常需要引用图片.倘或引用图片的链接是外网的,常常会出现加载过慢的情况,并且不稳定的图片来源不方便管理.所以如果建立一个博客专用的图片仓库,统一管理维护方面就方便得 ...
- acwing 2 零一背包问题
地址 https://www.acwing.com/problem/content/description/2/ 题目描述有 N 件物品和一个容量是 V 的背包.每件物品只能使用一次. 第 i 件物品 ...