js几种继承方式(六种)

JS实现继承的几种方式前言:大多数语言都支持两种继承方式: 接口继承和实现继承 ,而javaScript中无法实现接口继承,javaScript只支持实现继承,而且其实现继承主要是依靠原型链来实现。主要继承方式如下:1、原型链继承2、构造函数继承3、实例继承4、拷贝继承5、组合继承(原型链继承+构造函数继承)6、寄生组合式继承

JS继承的实现方式既然要实现继承,那么首先我们得有一个父类,代码如下:

// 定义一个动物类function Animal (name) {  // 属性  this.name = name || ‘Animal‘;  // 实例方法  this.sleep = function(){  console.log(this.name + ‘正在睡觉!‘);  }}// 原型方法Animal.prototype.eat = function(food) {  console.log(this.name + ‘正在吃:‘ + food);};

一、原型链继承核心: 将父类的实例作为子类的原型基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法。构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。function Cat(){}Cat.prototype = new Animal();Cat.prototype.name = ‘cat‘;

// Test Codevar cat = new Cat();console.log(cat.name); //catcat.eat(‘fish‘); //cat正在吃:fishcat.sleep(); //cat正在睡觉!console.log(cat instanceof Animal); //trueconsole.log(cat instanceof Cat); //true特点:  非常纯粹的继承关系,实例是子类的实例,也是父类的实例  父类新增原型方法/原型属性,子类都能访问到  简单,易于实现缺点:  无法实现多继承  来自原型对象的引用属性是所有实例共享的  创建子类实例时,无法向父类构造函数传参二、构造继承核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)基本思想:在子类型构造函数的内部调用超类构造函数,通过使用call()和apply()方法可以在新创建的对象上执行构造函数。

function Cat(name){  Animal.call(this);  this.name = name || ‘Tom‘;}// Test Codevar cat = new Cat();console.log(cat.name); //Tomcat.sleep(); //Tom正在睡觉console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // truecat.eat(‘fish‘); //报错特点:  解决了1中,子类实例共享父类引用属性的问题  创建子类实例时,可以向父类传递参数  可以实现多继承(call多个父类对象)缺点:  实例并不是父类的实例,只是子类的实例  只能继承父类的实例属性和方法,不能继承原型属性/方法  无法实现函数复用,每个子类都有父类实例函数的副本,影响性能三、实例继承核心:为父类实例添加新特性,作为子类实例返回

function Cat(name){  var instance = new Animal();  instance.name = name || ‘Tom‘;  return instance;}// Test Codevar cat = new Cat();console.log(cat.name) //Tomcat.sleep(); //Tom正在睡觉cat.eat(‘fish‘); // Tom正在吃:fishconsole.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false特点:  不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果缺点:  实例是父类的实例,不是子类的实例  不支持多继承四、拷贝继承function Cat(name){  var animal = new Animal();  for(var p in animal){    Cat.prototype[p] = animal[p];  }  Cat.prototype.name = name || ‘Tom‘;}

// Test Codevar cat = new Cat();console.log(cat.name) //Tomcat.sleep(); //Tom正在睡觉cat.eat(‘fish‘); //Tom正在吃:fishconsole.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:  支持多继承缺点:  效率较低,内存占用高(因为要拷贝父类的属性)  无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)五、组合继承核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用function Cat(name){  Animal.call(this);  this.name = name || ‘Tom‘;}Cat.prototype = new Animal();Cat.prototype.constructor = Cat;

// Test Codevar cat = new Cat();console.log(cat.name) //Tomcat.sleep(); //Tom正在睡觉cat.eat(‘fish‘); //Tom正在吃:fishconsole.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true特点:  弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法  既是子类的实例,也是父类的实例  不存在引用属性共享问题  可传参  函数可复用缺点:  调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)六、寄生组合继承核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点function Cat(name){  Animal.call(this);  this.name = name || ‘Tom‘;}(function(){  // 创建一个没有实例方法的类  var Super = function(){};  Super.prototype = Animal.prototype;  //将实例作为子类的原型  Cat.prototype = new Super();})();

// Test Codevar cat = new Cat();console.log(cat.name) //Tomcat.sleep(); //Tom正在睡觉cat.eat(‘fish‘); //Tom正在吃:fishconsole.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true

Cat.prototype.constructor = Cat; // 需要修复下构造函数特点:  堪称完美缺点:  实现较为复杂

参考链接:https://www.cnblogs.com/humin/p/4556820.html;参考链接:https://www.jb51.net/article/81766.htm

原文地址:https://www.cnblogs.com/lingdu87/p/9166427.html

时间: 2024-10-07 00:26:28

js几种继承方式(六种)的相关文章

第21篇 js四种继承方式

js是一个很自由的语言,没有强类型的语言的那种限制,实现一个功能往往有很多做法.继承就是其中的一个,在js中继承大概可以分为四大类,上面一篇文章也提及过一些,下面开始详细说说js的继承. 1.原型继承---最简单,最常用的 function funcA(){ this.show=function(){ console.log("hello"); } } function funcB(){ } funcB.prototype=new funcA(); var b=new funcB();

js几种继承方式比较

1.简单原型继承:没有基于类的方式进行管理,破坏了子类的原型,即子类构造器和父类构造器相同 function Person(name) { var _name; function init(name) { _name = name; } init(name); this.setName = function(name) { _name = name; } this.getName = function() { return _name; } } function Student(age) { v

js的5种继承方式——前端面试

js主要有以下几种继承方式:对象冒充,call()方法,apply()方法,原型链继承以及混合方式.下面就每种方法就代码讲解具体的继承是怎么实现的. 1.继承第一种方式:对象冒充 1 function Parent(username){ 2 this.username = username; 3 this.hello = function(){ 4 alert(this.username); 5 } 6 } 7 function Child(username,password){ 8 //通过以

js的6种继承方式

重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: 1 2 3 4 5

重新理解JS的6种继承方式

写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /*  * 约定  */ function Fun(){     // 私有属性  

重新理解JS的6种继承方式(转)

http://www.ayqy.net/ 写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: /* * 约定 */ function Fun(){ // 私有属性 var val = 1; // 私有基本属性 var arr = [

js的三种继承方式及其优缺点

第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.pr

[总结] js的2种继承方式详解

这篇文章主要介绍了javascript的2种继承方式,分析对象冒充和原型链方式的不同,需要的朋友可以参考下. js中继承可以分为两种:对象冒充和原型链方式. 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } function F2E(name,id){ this.

类设计中几种继承方式

 通过继承能够从已有的类派生出新的类,而派生类继承了基类的特征,包括方法.正如继承一笔财产要比自己白手起家容易一样,通过继承派生出的类通常比设计新类要容易得多.下面是可以通过继承完成的一些工作. ①可以在已有类的基础上添加功能. ②可以给类添加数据. ③可以修改类方法的行为. C++有三种继承方式:公有继承.保护继承和私有继承. 一.公有继承 公有继承是最常用的方式,它建立一种is-a关系,即派生类对象也是一个基类对象,可以对基类对象执行的任何操作,也可以对派生类对象执行. ①公有继承不建立