写在前面
继承的简介
继承”是JavaScript面向对象设计的重要一环,愿你认真读完本文,吃透继承的概念。
继承的核心
1. 继承方式一:原型链
1.1 介绍
原型链是实现继承最原始的模式,即通过prototype属性实现继承。
//父级-构造函数 function Father() { this.fatherProp = true } //父级-原型属性 Father.prototype.getFatherValue = function() { return this.fatherProp } //子级-构造函数 function Son() { this.sonProp = false } //子级-原型属性:继承父级 //即__proto__指向父级的prototype //若不理解请阅读《一张图彻底KO原型链(prototype,__proto__》 Son.prototype = new Father() //子级-添加原型方法 Son.prototype.getSonValue = function() { return this.sonProp } //创建子级的实例对象 var son = new Son() console.log(son.getFatherValue()) //true
1.2 解析:son实例对象是如何找到getFatherValue()方法的呢?
如果到最后都没找到,会发生什么呢?
//一个不存在的方法 console.log(son.getValue()) //ERROE:not a function
1.3 注意事项
重写父级原型链的方法或者添加父级原型链不存在的方法,必须在父级原型链代码之后。(这个很好理解,不放代码演示了)
通过原型链实现继承后,不能再使用字面量的方式创建原型对象,因为会覆盖原型链。
//子级-原型属性:继承父级 Son.prototype = new Father() //不能像下面这样,这样会使得上面的代码无效 //因为这相当于重新创建了一个原型对象 Son.prototype = { getSonValue: function() { return this.sonProp } }
1.4 原型链实现继承的弊端
世间万事万物都不可能十全而十美,原型链虽然强大,但也存在缺陷。
原型链中引用类型的属性会被所有实例共享的,即所有实例对象使用的是同一份数据,会相互影响。
function Father() { this.arr = [1,2,3] } function Son() { } Son.prototype = new Father() var son1 = new Son() console.log(son1.arr) //1,2,3 var son2 = new Son() son2.arr.push(4) console.log(son2.arr) //1,2,3,4 console.log(son1.arr) //1,2,3,4
无法向父级构造函数传参
2. 继承方式二:借用构造函数
2.1 介绍
方式一中引用类型带来的问题可借用构造函数的方式解决。其核心思想是:在子级构造函数中调用父级构造函数。
如何实现在一个构造函数中调用另一个函数?——call()和apply()
function Father() { this.arr = [1,2,3] } function Son() { //call的第一个函数是this指向的对象,即构造函数的实例对象 Father.call(this) /*上面代码等同于下面这段代码: (function() { this.arr = [1,2,3] }).call(this) */ } var son1 = new Son() console.log(son1.arr) //1,2,3 var son2 = new Son() son2.arr.push(4) console.log(son2.arr) //1,2,3,4 console.log(son1.arr) //1,2,3
//解决传参问题: function Father(name) { this.name = name } function Son(name) { Father.call(this, name) } var son1 = new Son("小名") console.log(son1.name) //小名 var son2 = new Son("一灯") console.log(son2.name) //一灯
2.2 借用构造函数的缺陷
这种方式是通过构造函数实现的,当然也把构造函数自身的问题带过来了——破坏了复用性。因为每个实例都创建了一份副本。
3. 组合继承
3.1 介绍
组合继承 = 原型链 + 借用构造函数。取其长避其短:共享的用原型链,各自的借用构造函数
function Father(name) { this.name = name this.arr = [1,2,3] } Father.prototype.getName = function() { console.log(this.name) } function Son(name, age) { Father.call(this, name) this.age = age } Son.prototype = new Father() Son.prototype.constructor = Son Son.prototype.getAge = function() { console.log(this.age) } var son1 = new Son("小名", 23) son1.arr.push(4) console.log(son1.arr) //1,2,3,4 son1.getName() //小名 son1.getAge() //23 var son2 = new Son("一灯", 24) console.log(son2.arr) //1,2,3 son1.getName() //一灯 son1.getAge() //24
3.2 解析
借用构造函数部分:
Father.call(this, name)——name来自Father
this.age = age; Son.prototype.constructor = Son——age来自Son
原型链部分:
Father.prototype.getName——getName方法来自Father.prototype
Son.prototype.getAge——getAge来自Son.prototype
后记
关于继承的后三种方式马上推出,期待你的点赞&关注!
以上所述是小编给大家介绍的js继承方式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍js实现继承的5种方式,包括了js实现继承的5种方式的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js实现继承的5种方式。分享给大家供大家参考,具体如下: 1、继承第一种方式:对象冒充 2、继承第二种方式:call()方法方式 call方法是Function类中的方法 call方法的第一个参数的值赋值给类(即方法)中出现的this call方法的第二个参数开始依次赋值给类(
本文向大家介绍JS中继承实现的几种方式?相关面试题,主要包含被问及JS中继承实现的几种方式?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 1、原型链继承,将父类的实例作为子类的原型,他的特点是实例是子类的实例也是父类的实例,父类新增的原型方法/属性,子类都能够访问,并且原型链继承简单易于实现,缺点是来自原型对象的所有属性被所有实例共享,无法实现多继承,无法向父类构造函数传参。 2、构造继
主要内容:public、protected、private 修饰类的成员,public、protected、private 指定继承方式,改变访问权限C++继承的一般语法为: class 派生类名:[继承方式] 基类名{ 派生类新增加的成员 }; 继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。此项是可选项,如果不写,默认为 private(成员变量和成员函数默认也是 private)。 现在我们知道,
本文向大家介绍JS实现继承的几种常用方式示例,包括了JS实现继承的几种常用方式示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS实现继承的几种常用方式。分享给大家供大家参考,具体如下: 1,原型链继承 运行结果: 2,构造继承 运行结果: 3,组合继承 运行结果: 4,寄生组合继承 运行结果: 感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://
本文向大家介绍js中实现继承的五种方法,包括了js中实现继承的五种方法的使用技巧和注意事项,需要的朋友参考一下 借用构造函数 这种技术的基本思想很简单,就是在子类型构造函数的内部调用超类型的构造函数。另外,函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在新创建的对象上执行构造函数。 从中可以看到,继承来的只有实例属性,而原型上的属性是访问不到的。这种模式
本文向大家介绍浅谈JS继承_寄生式继承 & 寄生组合式继承,包括了浅谈JS继承_寄生式继承 & 寄生组合式继承的使用技巧和注意事项,需要的朋友参考一下 5.寄生式继承 与寄生构造函数和工厂模式类似,创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象。 在上述例子中,createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。 anotherPerso
这里我们只介绍继承、原型的基本概念和其常见使用方式。要完整理解继承,需要读者自行补充阅读面向对象编程的发展历史和一些核心思想。简而言之,继承是为了更好的代码或接口复用。 举个例子,如果我们要在界面上构建若干个面板组件,每个面板包含不同的内容和元素,但要求每个面板都可以被隐藏或显示、漂浮或定位,那么最原始的方法是在每个面板对象中添加show/hide/float/dock方法。 这样就存在大量的代码
本文向大家介绍JavaScript的9种继承实现方式归纳,包括了JavaScript的9种继承实现方式归纳的使用技巧和注意事项,需要的朋友参考一下 不同于基于类的编程语言,如 C++ 和 Java,JavaScript 中的继承方式是基于原型的。同时由于 JavaScript 是一门非常灵活的语言,其实现继承的方式也非常多。 首要的基本概念是关于构造函数和原型链的,父对象的构造函数称为Parent