三分钟搞定JS继承
发布日期:2022-02-22 16:04:46 浏览次数:24 分类:技术文章

本文共 3694 字,大约阅读时间需要 12 分钟。

一、原型链继承

  • js中无法实现接口继承,依靠原型链来实现继承
基本思想:通过改变prototype的指向形成实例和原型之间的原型链

instanceSub->subType.prototype(instanceSuper)->superType.prototype-> Object.prototype->null

  • 实现步骤
  1. 子对象的原型是父对象的实例 subType.prototype = instanceSuper;subType.prototype=new superType();
  2. 父对象的实例上添加 constructor 属性 指向 subType subType.prototype.constructor = subType;
改变prototype
  1. 动态修改prototype的属性时,会影响所有已经创建和新创建的实例。
  2. 重写prototype,即将prototype赋值为新的对象(对象字面量形式)时,不会影响已经创建的实例,会影响后序创建的实例
function SuperType() {
this.property = true; } SuperType.prototype.getSuperValue = function() {
return this.property; } function subType() {
this.subproperty = false; } var instanceSuper = new SuperType(); subType.prototype = instanceSuper; //子对象的原型是父对象的实例 //SuperType的实例作为 subType的原型 subType.prototype.constructor = subType;//添加 constructor 属性 指向 subType //子对象的原型设置为父对象的实例后,再向子对象原型添加方法 subType.prototype.getSubValue = function() {
return this.subproperty; } var instanceSub = new subType(); //子对象能够继承到父对象的方法 console.log(instanceSub.getSuperValue()); //true console.log(instanceSub.getSubValue()); //false
原型链的问题
1. 原型链上的属性都是共享的,包含引用类型值(eg:数组类型)的原型属性会被所有实例共享,一改全改2. 创建子类型的实例时 ,不能向父类型的构造函数中传递参数3. 解决:使用构造函数解决原型链继承的问题

二、构造函数继承

基本思想:在子对象的构造函数内部调用父类的构造函数
function SubType(type, price) {
SuperType.call(this, type);//调用父类构造方法实现继承,同时可以传参 }
  • 实例本身不能继承构造函数,实例可以使用构造函数中的属性和方法是由于this
构造函数实现继承的问题
  1. 实例继承自构造函数,而构造函数原型上的属性和方法对实例对象不可见.
  2. 构造函数模式的问题:方法都在构造函数中定义,无法复用

三、原型+构造函数组合继承(常用)

基本思想:使用原型链实现对原型属性和方法的继承,构造函数实现对实例属性的继承
原型+构造函数组合继承的问题: 调用两次超类构造函数。1.创建子类原型 2. 在子类构造内部调用父类构造
function SuperType(name) {
this.name=name; this.color = ['red', 'green', 'blue']; } SuperType.prototype.sayName=function(){
console.log(this.name); } function SubType(name,age) {
this.age = age; SuperType.call(this,name);//调用父类构造方法实现继承. } //继承构造函数原型上的属性和方法 SubType.prototype=new SuperType();//调用父类构造函数 SubType.prototype.constructor=SubType; SubType.prototype.sayAge=function(){
console.log(this.age); } var sub = new SubType('lily',18); sub.color.push('black'); console.log(sub.color);//["red", "green", "blue", "black"] var sub2 = new SubType('nacy',12); console.log(sub2.color);//["red", "green", "blue"]

四、原型式继承

基本思想:创建一个生成临时构造函数的函数,借助原型,基于已有的对象创建新对象
function object(o){
function F(){
};//创建临时构造函数 F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F();//返回临时构造函数的新实例 } var person2=object(person);//则 person2 的原型为person
  • Object.create() 方法规范化了原型式继承,可以使用Object.create()替换object函数

  • Object.create() 是一个系统内置的函数,接收一个参数,一般是对象,返回新创建的对象,并且对象的原型指向传入的参数。

    创建一个空对象,空对象的原型,是传入的参数。

  • Object.create(null); null没有原型,没有prototype属性 ,所以没有toString方法

  • 使用bind函数将函数指向为null后,该函数也没有prototype属性。

原型式继承的问题
  • 引用类型值的属性会被所有实例共享

五、寄生式继承

基本思想:原型式继承+工厂模式(创建一个仅用于封装继承过程的函数,该函数在内部为对象添加属性和方法,然后返回对象)
寄生式继承的问题:不能做到函数复用
function object(o){
function F(){
}; F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F(); } function createAnother(original){
var clone=object(original); clone.sayHi=function(){
//添加函数后返回该对象,函数不共享 console.log('hi'); } return clone; } var person={
name:'张三', friends:['lily','nacy','tom'] } var person2=createAnother(person); person2.sayHi();

六、寄生组合式继承(引用类型的理想继承)

基本思想: 寄生式继承+组合继承
  • 构造函数 继承 属性;原型链混成形式 继承 方法
function object(o){
function F(){
}; F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F(); } //创建超类构造函数的副本,赋值给子类型的原型 function inheritPrototype(subType,superType){
//两个参数:子类构造函数,父类构造函数 var prototype=object(superType.prototype);//创建超类型原型的副本 prototype.constructor=subType; subType.prototype=prototype;//将新创建的对象赋值给子类型的原型 }

转载地址:https://blog.csdn.net/Conradine_Lian/article/details/105299923 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:DOM文档对象模型(思维导图版)
下一篇:JS引用数据类型概览(思维导图版)

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月07日 10时24分36秒