博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js之继承
阅读量:7210 次
发布时间:2019-06-29

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

js中的继承有多种方式,因为其不像java一样有可以直接类继承(es6 中扩展了extend),他用的是原型链继承

首先我们来构造一个动物的父类

function Animal (name = 'Animal'){            this.name = name;            this.play = function(){                console.log( this.name+"can play");            }        } // 定义了name 属性和play方法        Animal.prototype.say = function(){            console.log("hello,i can speak Animal language")        } // 在原型链上挂载了 say 方法

 在该父类中我们有一个play的实例私有方法和一个say方法,该方法为原型链共享方法,所有的实例都可以修改该方法。

1.原型继承,将子类的原型指向父类的实例,这样子类的实例就可以通过原型链去继承父类的方法以及属性

function Cat(){}                Cat.prototype = new Animal();        Cat.prototype.name = 'lowcat';                var cat = new Cat();         console.log(cat.name); //输出lowcat        console.log(cat.say()); //输出 hello, i can speak Animal language        console.log(cat.play()); //输出 lowcat can play        console.log(cat instanceof Animal); // true        console.log(cat instanceof Cat); // true

优点 1. 非常纯粹的继承关系 实例是子类的实例 也是父类的实例

 2. 父类新增原型方法/原型属性 子类都能访问到
 3. 简单
 缺点 1.要想为子类新增原型属性和方法,必需要在new Animal()语句执行之后 (因为先要把原型指向搞清楚)
 2.无法实现多继承
 3.来自原型的所有属性被所有实例共享
 4.创建子类实例时,无法想父类构造函数传参(因为直接执行父类的构造函数)

2.构造继承(使用call函数改变当亲父类的上下文)

function Dog(name = 'pony'){             Animal.call(this);             this.name = name ;         }
var dog = new Dog("tony");         console.log(dog.name); //输出tony         console.log(dog.play());// 输出 i can play console.log(dog.say()); 输出错误         console.log(dog instanceof Animal); //false         console.log(dog instanceof Dog);  // true

优点 :1. 解决了原型继承中所有子类实例共享父类的属性与方法

 2. 创建子类实例是,可以向父类传递参数
 3. 实现了多继承
 缺点 :1.实例斌不是父类的实例,只是子类的实例
 2.只能继承父类的实例属性和方法,不能继承原型属性方法
3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
 此继承方式使用了call函数 改变当前子类构造函数的运行环境,所有子类能够访问到父类的方法,但却不能访问原型链,因为在原型链上并没有实质的改变;
三、工厂模式继承(内部使用obj直接作为父类的实例,然后return 回去当作子类的实例)

function Fish (name = "fish") {             var obj = new Animal();             obj.name = name;             return  obj;         }
var fish = new Fish("fish");         console.log(fish.name); //输出 fish         console.log(fish.play()); // 输出 i can play         console.log(fish.say()); // 输出hello ,i can speak Animal lanvuage         console.log(fish instanceof Animal);// true         console.log(fish instanceof Fish); //true

优点: 1.不限制调用方式,不管是new 还是直接调用 返回的对象具有相同的效果

 缺点:1.实例是父类的实例,不是子类的实例
            2.不支持多继承

四、拷贝继承

function Mouse(name ="mouse"){              var animal = new Animal();              for(var p in animal){                  Mouse.prototype[p] = animal[p];              }              Mouse.prototype.name = name;          }
var mouse = new Mouse("Jack");         console.log(mouse.name); // Jack         console.log(mouse.play()); // i can play         console.log(mouse.say()); // hello, i can speak Animal language         console.log(mouse instanceof Animal); //ture         console.log(mouse instanceof Mouse) // ture

优点 1.支持多继承 (多复制几个父类)

 缺点 1.效率低,用了遍历copy(内存占用高)
          2.无法获取父类的不可枚举方法(在对象中的atrributes object(属性描述对象)可以设置对象属性的状态)

五、寄生组合继承(首先将父类的上下文拿到子类当中,在将子类的原型指向父类的原型,这里并不是直接指向)

function Bird(name ="bird"){               Animal.call(this);               this.name = name;           }           (function(){                 var Obj = function(){}; // 首先创建一个空对象                 Obj.prototype = Animal.prototype; // 将空对象的原型指向父类的原型                 Bird.prototype  = new Obj(); // 将子类的原型指向 空对象的实例,见解继承了父类的原型                 Bird.prototype.constructor = Child; // 因为此时obj的原型的constrcutor指向了obj的构造函数,手动修复指向           })();          var bird = new Bird();         console.log(bird.name);         console.log(bird.play());         console.log(bird.say());         console.log(bird instanceof Animal);         console.log(bird instanceof Bird);

这个方法十分完美,解决了组合继承的两次实例化问题

转载于:https://www.cnblogs.com/maoxiaodun/p/10007759.html

你可能感兴趣的文章
可信云认证累计达20项,腾讯云技术创新能力再获专业认可
查看>>
十周后,62%的PHP网站将运行在一个不受支持的PHP版本上
查看>>
战胜阿里和腾讯,Ripple已经获得200家跨境支付客户!
查看>>
推销自己的前端技术书籍
查看>>
Visual Studio 15.8 Preview 3支持多点编辑功能
查看>>
Pravega应用实战:为什么云原生特性对流处理很重要?
查看>>
Amazon发布可持续性数据集,可用于多个领域的数据分析
查看>>
SendGrid是如何扩展它的邮件传送系统的
查看>>
Oracle发布Oracle数据库的官方Node.js驱动node-oracledb
查看>>
Spring 5.0 GA版本发布,支持JDK9及反应式编程
查看>>
wemall app商城源码Android之支付宝通知处理类
查看>>
利用已有的大数据技术,如何构建机器学习平台
查看>>
Stream从Python切换到Go的原因
查看>>
Python将迁移到GitHub
查看>>
Linux系统安装MySql步骤及截屏
查看>>
如何理解阿里月饼事件中各方的表现
查看>>
浅谈line-height
查看>>
php二维数组指定其键名对其排序的方法
查看>>
用什么PHP框架最好?框架?还不如用开源系统吧
查看>>
JS 设计模式 一(接口)
查看>>