总结JS继承的六种方式
1. 继承
1.1语法
// 父类class Father{ }
// 子类继承父类class Son extends Father { }
例如:
class Father {constructor(sonname) {this.sonname= sonname;}say() {console.log('你的姓是' + this.sonname);}}
class Son extends Father{// 这样子类就继承了父类的属性和方法}let yours= new Son('王');yours.say(); //结果为 你的姓是王
子类继承了父类的属性和方法。
1.2 子类使用super关键字访问父类的方法
//定义了父类class Father {constructor(x, y) {this.x = x;this.y = y;}sum() {console.log(this.x + this.y);}}//子元素继承父类class Son extends Father {constructor(x, y) {super(x, y); //使用super调用了父类中的构造函数}}var son = new Son(1, 2);son.sum(); //结果为3
注意:
- 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行 子类的
- 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这 个方法(就近原则)
- 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用 父类的构造函数,super 必须在子类this之前调用
// 父类有加法方法class Father {constructor(x, y) {this.x = x;this.y = y;}sum() {console.log(this.x + this.y);}}// 子类继承父类加法方法 同时 扩展减法方法class Son extends Father {constructor(x, y) {// 利用super 调用父类的构造函数 super 必须在子类this之前调用,放到 this之后会报错super(x, y);this.x = x;this.y = y;}sub() {console.log(this.x ‐ this.y);}}var son = new Son(5, 3);son.sub(); //运行结果为2 调用了子类中定义的相减的方法son.sum();//运行结果为8 子类继承了父类中的相加的方法
1.3 时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用.
- constructor中的this指向的是new出来的实例对象
- 自定义的方法,一般也指向的new出来的实例对象
- 绑定事件之后this指向的就是触发事件的事件源
2.原型链
- 当访问一个对象的属性(包括方法时),首先查找这个对象自身有没有该属性。
- 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
- 如果还没有就查找原型对象的原型(Object的原型对象)。依此类推一直找到为null为止。
- __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。
3.call()
this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。只不过apply第二个参数必须传入的是一个数组,而call 第二个参数可以是任意类型。
call(thisObject,arg1,arg2...)
function fn(x, y) {console.log('我想喝手磨咖啡');console.log(this);console.log(x + y);}var o = {name: 'andy'};// fn();// 1. call() 可以调用函数fn.call();// 2. call() 可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象fn.call(o, 1, 2);
4. 借用父构造函数继承属性
- 先定义一个父构造函数(this指向为window)
- 再定义一个子构造函数(this指向为new出的实例化对象)
- 子构造函数通过call()改变父的this指向继承父构造函数属性
function Hui(uname, age) {// this 指向父构造函数的对象实例this.uname = uname;this.age = age;}function Chen(value){this.value=value;}// 2 .子构造函数 function Miao(uname, age, value) {// this 指向子构造函数的对象实例Hui.call(this, uname, age);Chen.call(this,value);}var Miao = new Miao('辉', 21, 100);console.log(Miao);
- 优点:避免了原型链继承的两个缺点,可以向父类传参,且不会造成原型属性共享的问题(因为父类构造函数中的属性继承到子类构造函数中,而非原型对象中)。
- 缺点:不能继承原型属性,无法实现函数复用,所有方法都只能放在构造函数中。
5.原型链继承
原型链是针对原型对象的,在查找实例属性时,现在实例中查找,如果没有找到,再到obj.__proto__(=f1.prototype)原型对象,再到f1.prototype.__proto__(=f2.prototype),依次向上查找。
function Father(){this.color = 'red';
}
Father.prototype.getName = function(){console.log(this.name);
}function Son(){}
Son.prototype = new Father();//将父类的实例赋给子类的原型var son = new Son();
console.log(son);
打印结果:
将Father实例化给Son的原型对象,再实例化Son赋值给变量son,打印结果可见son通过prototype指向Father函数,Father函数通过prototype指向Object对象,让Son来继承其中的属性。
注意:原型对象的构造函数是函数本身,因此每个构造函数的prototype对象可以看做一个实例化对象。
优点:能够继承构造函数属性,也能够继承原型属性。
缺点:
1.首先属性值为引用类型值的原型属性被修改后可能会影响到所有的实例,并在此继承方式中,构造函数中的属性会继承到子类型,成为子类的原型对象的属性,这也是要在构造函数中定义属性,在原型中定义公共方法的原因。2.在创建子类的实例时,不能向父类的构造函数中传递参数。
6.组合继承
组合继承(combination inheritance),也叫做伪经典继承,指的是将原型链和借用父构造函数组合到一块,其思路是用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。
function Person(name, age) {this.name = name,this.age = age,this.setAge = function () { }
}
Person.prototype.setAge = function () {console.log("111");
}
function Student(name, age, price) {Person.call(this, name, age);this.price = price;this.setScore = function () { };
}
Student.prototype = new Person();
Student.prototype.constructor = Student;//组合继承也是需要修复构造函数指向的
Student.prototype.sayHello = function () { };
var s1 = new Student('Tom', 20, 15000);
var s2 = new Student('Jack', 22, 14000);
console.log(s1);
console.log(s1.constructor);
Student;
console.log(s2.constructor);
console.log(Person);
运行结果:
未完待续
总结JS继承的六种方式相关推荐
- js继承的六种方式详解--认真看完你就会了
今天 主要来研究一下继承这个东西 继承 共分为六种继承方式: 原型链继承 盗用构造函数继承 组合继承 实例继承(原型式继承) 寄生式继承 寄生式组合继承 原型链继承 原型链继承是ES主要继承方法,其中 ...
- js延迟加载的六种方式
1. defer 属性 HTML 4.01 为<script>标签定义了defer属性.标签定义了defer属性元素中设置defer属性,等于告诉浏览器立即下载,但延迟执行标签定义了def ...
- js 继承的几种方式
JS继承的实现方式: 既然要实现继承,那么首先我们得有一个父类,代码如下: function Animal(name) {// 属性this.name = name || '小白';// 实例方法th ...
- JS继承六种方式详解
js继承的6种方式: 想要继承,就必须要提供个父类(继承谁,提供继承的属性) 继承在js中占有非常重要的地位,那么在js中有很多中继承的方式,不过每一种继承方式都有优缺点.下面就列举几种继承的方式: ...
- [Web前端基础] CSS优先级、JS运算优先级、CSS设置在第几行进行超出部分省略号、JS设置元素样式的六种方式
CSS优先级 !important> 行内样式 > id选择器 > 类选择器 > 标签选择器 > 通配符选择器 > 继承 如果有多个复合选择器选中同一个元素,则需要 ...
- php中 继承中的概念,JavaScript_JavaScript中的继承方式详解,js继承的概念
js里常用的如下 - phpStudy...
JavaScript中的继承方式详解 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于 ...
- 前端html继承的方式,好程序员web前端教程之JS继承实现方式解析
好程序员 web 前端教程 之JS 继承实现方式解析 , JS 是 Web 前端三要素之一,也是每一个初学前端的同学遭遇的第一条拦路虎.很多人反应 JS 学习不易,各类知识点概念及应用常常让人抓耳挠腮 ...
- web程序前后台功能实现_好程序员web前端教程之JS继承实现方式解析
好程序员web前端教程之JS继承实现方式解析,JS是Web前端三要素之一,也是每一个初学前端的同学遭遇的第一条拦路虎.很多人反应JS学习不易,各类知识点概念及应用常常让人抓耳挠腮.在接下来的北京Web ...
- 阅读JS小红书之继承的六种实现方法
简介: 因为JS的不是面向对象语言,因此没有接口继承这一东西,但是JS有很多骚操作可以实现继承,继承无非就是子类拥有父类的属性和方法,下面就介绍6种变现实现JS继承的方法 1.最简单的继承实现(原型链 ...
- 如何用原型链的方式实现一个 JS 继承?
大家好,我是前端西瓜哥.今天讲一道经典的原型链面试题. 原型链是什么? JavaScript 中,每当创建一个对象,都会给这个对象提供一个内置对象 [[Prototype]] .这个对象就是原型对象, ...
最新文章
- 数据结构期末考试题目---笔记(SYSU)
- linux如何判断光盘是否挂载,LInux下如何挂载光盘找rpm包的方法步骤
- 抽象类必须要有抽象方法吗?
- @程序员,区块链开发平台避坑指南!
- C# pdf 转图片 and 创建百度AI文字识别应用(识别图片中的文字和数字)
- 前端学习-jQuery源码学习
- 24. Declear non-member functions when type conversions should apply to all parameters
- source insight设置Courier new字体
- 计算机样式的ppt,计算机应基础使用样式修饰页面.ppt
- 《统计自然语言处理》(宗成庆)学习笔记(一)
- linux卸载驱动命令,卸载打印机驱动程序 (Linux)
- C语言学习-翁凯(目录总章)
- WordPress纯代码高仿 无觅相关文章 图文模式功能
- 2019 ICPC 南京区域赛 - H Prince and Princess(博弈+思维)
- 如何成为很厉害的程序员?- 读《精进》
- WebAPIs-第01天笔记
- 邮政收件箱界面html,时尚邮件收件箱UI设计效果
- 台式电脑由哪些部件组成,有哪些配件组成?
- 从水处理速度梯度的公式,复习一下物理学常用公式,擦边爱因斯坦质能方程
- Python+OpenCV利用KNN背景分割器进行静态场景行人检测与轨迹跟踪
热门文章
- 机器之心深度研学社每周干货:2017年第13周
- php有个schost.exe_windows找不到svchost.exe(附图)
- PS2有线手柄的SPI协议
- 使用instsrv.exe+srvany.exe将应用程序安装为windows服务的方法
- Windows创建用户定义的服务(srvany.exe和instsrv.exe )
- cecore.cls.php 08cms,动态分析小示例| 08CMS SQL 注入分析
- Linux操作命令提示符
- php yar swoole 比较,Hprose 和 Yar 的性能比较
- iOS面试题大全2021(附答案)
- 配置ext邮箱服务器,Extmail实现邮件服务器