实现继承的几种方式及工作原理
栏目: JavaScript · 发布时间: 6年前
内容简介:可以自己打印一下,看一下结果1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例2.父类新增原型方法/原型属性,子类都能访问到
function Animal() { this.name = "animal"; this.arrt = [1, 2] } Animal.prototype = { sayName: function () { alert(this.name); } } function Dog() { this.color = "灰色" } Dog.prototype = new Animal(); Dog.prototype.sayColor = function () { alert(this.color); } var dog = new Dog(); var dog1 = new Dog(); console.log(dog); dog.arrt.push(5); console.log(dog1); dog.sayColor(); dog.sayName(); 复制代码
可以自己打印一下,看一下结果
优点1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例
2.父类新增原型方法/原型属性,子类都能访问到
3.简单,易于实现
缺点
1.包含引用类型值的原型属性会被所有实例共享,这会导致对一个实例的修改会影响另一个实例。
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数。由于这两个问题的存在,实践中很少单独使用原型链。
-
借用构造函数
也称 "伪造对象" 或 "经典继承",在子类型构造函数的内部调用超类型构造函数。函数不过是在特定环境中执行代码的对象,因此通过apply(),call()方法可以在(将来)新建对象上执行构造函数,即 在子类型对象上执行父类型函数中定义的所有对象初始化的代码。结果每个子类实例中都具有了父类型中的属性以及方法
function Animal(name){ this.name = name; this.colors = ["red","gray"]; } function Dog(name){ //继承了Animal Animal.call(this,"mary");//在子类型构造函数的内部调用超类型构造函数 this.color = "gray"; } Animal.prototype.sayName = function(){ alert(this.name); } var dog = new Dog(); var dog1=new Dog(); dog.colors.push("hhh"); console.log(dog.colors);//red gray hhh console.log(dog1.colors);//red gray Animal.prototype.swif="hua"; console.log(dog.swif);//undefined var animal = new Animal(); console.log(animal); //如果将函数定义在构造函数中,函数复用无从谈起 dog.sayName(); //在超类型的原型中定义的方法,对于子类型而言是无法看到的 复制代码
优点
1.解决了1中,子类实例共享父类引用属性的问题
2.创建子类实例时,可以向父类传递参数
3.可以实现多继承(call多个父类对象)
缺点
1.实例并不是父类的实例,只是子类的实例
2.只能继承父类的实例属性和方法,不能继承父类原型属性/方法
3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
-
组合函数
组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的 技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方 法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数 复用,又能够保证每个实例都有它自己的属性
function Animal(name){ this.name = name; this.colors = ["red","gray"]; } function Dog(name){ //继承了Animal(属性) Animal.call(this,name); this.color = "gray"; } Animal.prototype.sayName = function(){ alert(this.name); } //继承方法 Dog.prototype = new Animal(); Dog.prototype.constructor = Animal; var dog = new Dog("2"); dog.colors.push("hhh"); console.log(dog); var animal = new Animal(); console.log(animal); dog.sayName(); //可以调用 复制代码
优点
1.可以继承实例属性/方法,也可以继承原型属性/方法
2.既是子类的实例,也是父类的实例
3.不存在引用属性共享问题
4.通过call继承父类的基本属性和引用属性并保留能传参的优点
5.函数可复用
缺点
1,子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 搞懂 JavaScript 继承原理
- C3 算法:Python 多重继承的内部原理
- 深入 JavaScript 原型继承原理——babel 编译码解读
- 多态、继承、this、super、及多态执行方法时的原理
- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hit Refresh
Satya Nadella、Greg Shaw / HarperBusiness / 2017-9-26 / USD 20.37
Hit Refresh is about individual change, about the transformation happening inside of Microsoft and the technology that will soon impact all of our lives—the arrival of the most exciting and disruptive......一起来看看 《Hit Refresh》 这本书的介绍吧!