当前位置: 首页 > news >正文

深圳我的网站广州线下培训机构停课

深圳我的网站,广州线下培训机构停课,网站后台关键词设置,企业网站开发数据库设计文章目录详解ES5类的实现和继承的实现1. 前言2. ES5 中类的实现3. ES5 中类继承的实现3.1 原型链继承3.2 盗用构造函数实现继承3.3 组合继承(原型链 盗用构造函数)4. 总结详解ES5类的实现和继承的实现 1. 前言 ES5 中类的实现以及类的继承是 JS 中一个…

文章目录

  • 详解ES5类的实现和继承的实现
    • 1. 前言
    • 2. ES5 中类的实现
    • 3. ES5 中类继承的实现
      • 3.1 原型链继承
      • 3.2 盗用构造函数实现继承
      • 3.3 组合继承(原型链 + 盗用构造函数)
    • 4. 总结

详解ES5类的实现和继承的实现

1. 前言

ES5 中类的实现以及类的继承是 JS 中一个不得不跨越和征服的高点。不论是在学习的过程中为了更好的理解 ES 6 class 的实现方法以及学习原型链和构造函数等知识,还是为了在面试中应对面试官让描述ES5类和继承的原理甚至手动实现ES5继承(博主在面试中就遇到过)。这个高点必须拿下,下面就让我们来一步一步的详细解析,刨根问底吧!

2. ES5 中类的实现

ES5 中使用构造函数来实现类,在分析code前先简单看一下以下概念,不明白没关系,在示例代码中有详细的说明:

  • 构造函数:其实就是一个函数,在这个函数中定义属性和方法
  • 实例:通过 new 构造函数 得到的就是一个实例。
  • 实例属性(方法):这个属性(方法)在构造函数中定义。特别注意:只有实例可获取
  • 原型链属性(方法):这个属性(方法)在构造函数的原型链上定义。特别注意,原型链属性在实例间是共享的,在示例中有说明和演示
  • 静态属性(方法):这个属性(方法)直接定义在构造函数上。特别注意:只有构造函数可获取

通过一个示例来说明ES5中类的实现。其中Person就是一个构造函数,name, age, star就是实例属性,init 就是实例方法,nationality就是原型链属性,home就是原型链方法,universe就是静态属性,shuttle就是静态方法。

// ES5 类
// 构造函数方式实现类
function Person(name, age) {// 实例属性,只能实例使用,构造函数获取不到this.name = name;this.age = age;   this.star = 'Earth'; // console.log(Person.star);  undefined// 实例方法,也只能实例使用this.init = function() {console.log(`${this.name} is fighting: ${this.age}!`);};
};
// 原型链属性,可被多个实例共享,比如原型链属性是引用值时,是共享的。也只能实例使用
Person.prototype.nationality = ['China'];   // console.log(Person.nationality); undefined
// 原型链方法
Person.prototype.home = function() {console.log(`${this.name}'s home is in ${this.star}`);
};// 静态属性,实例无法获取, 只能构造函数本身使用
Person.universe = 'TheMilkyWay';    // console.log(arrow.universe); undefined
// 静态方法
Person.shuttle = function() {console.log('shuttling');
};const arrow = new Person('Arrow', 12);
console.log('实例----------------------------');
console.log(arrow.name, arrow.age);     // Arrow 12 父类的实例属性
arrow.init();     // Arrow is fighting: 12! 父类的实例方法console.log(arrow.nationality);    // [ 'China' ] 父类原型链属性
arrow.home();   // Arrow's home is in Earth 父类原型链方法console.log(Person.universe);   // TheMilkyWay  构造函数静态属性
Person.shuttle();    // shuttling  构造函数静态方法// Arrow 12
// Arrow is fighting: 12!
// Arrow's home is in Earth
// TheMilkyWay
// shuttlingconst tom = new Person('Tom', 22);
console.log('\n原型链属性共享----------------------------');
console.log(tom.nationality);   // 父类原型链属性,引用类型
tom.nationality.push('French');    // 原型链上的属性是共享的
console.log(tom.nationality);  
console.log(arrow.nationality);// [ 'China' ]
// [ 'China', 'French' ]
// [ 'China', 'French' ]

3. ES5 中类继承的实现

首先需要提出的是:在ES5中实现继承主要采用组合继承(也称伪经典继承),采用原型链 + 盗用构造函数 来实现继承。但为了更好的追根溯源,明白其根源,博主这里先分别讲解原型链继承和盗用构造函数继承的实现方法和优劣势,然后再讲解组合继承。以第2节中的 Person 构造函数为父类。

3.1 原型链继承

基本思想:通过原型继承多个引用类型的属性和方法。实现的原理需要回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。试想一下,如果原型是另一个类型的实例呢?那是不是就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向它所对应的构造函数。这样就在实例和原型之间构造了一条原型链。这段话需要好好理解一下。

// ES5 继承
// 1. 原型链继承,可以继承父类的实例属性和方法以及父类原型链上的属性和方法,但是子类在实例化时不能给父类的构造函数传参
function Man_1() {};
Man_1.prototype = new Person();const bullet_1 = new Man_1();
console.log('bullet-1-----------------------------------------');
console.log(bullet_1.star);   // Earth 可以获取到父类的实例属性
console.log(bullet_1.nationality);   // [ 'China' ] 可以获取到父类原型链上的属性
bullet_1.init();    // undefined is fighting: undefined!  可以使用父类的实例方法,但是没有参数传递
bullet_1.home();    // undefined's home is in Earth  可以使用父类的原型链上的方法,但是没有参数传递
// Earth
// [ 'China' ]
// undefined is fighting: undefined!
// undefined's home is in Earth

原型链继承的优劣:

  • 优势:可以继承父类的实例属性和方法以及父类原型链上的属性和方法

  • 劣势:子类在实例化时不能给父类的构造函数传参

3.2 盗用构造函数实现继承

盗用构造函数继承(constructor stealing, 也称对象伪装或者经典继承)基本思想:在子类构造函数中调用父类构造函数。因为毕竟函数就是在特定上下文中执行代码的简单对象,所以可以使用 apply()call()方法以新创建的对象为上下文执行构造函数。

// 2. 盗用构造函数(constructor stealing, 也称对象伪装或者经典继承)继承,子类可继承父类的实例属性和方法同时子类在实例化时可以给父类的构造函数传参,但是无法继承父类原型链上的属性和方法
function Man_2(...args) {Person.call(this, ...args)
};const bullet_2 = new Man_2('bullet', 32);
console.log('\nbullet-2-----------------------------------------');
console.log(bullet_2.name, bullet_2.age, bullet_2.star);   // bullet 32 Earth 可以获取到父类的实例属性,并且可以传递参数
bullet_2.init();  // bullet is fighting: 32! 可以获取到父类的实例方法,并且可以传递参数console.log(bullet_2.nationality);  // undefined 无法获取到父类原型链上的属性, 自然方法也获取不到// bullet 32 Earth
// bullet is fighting: 32!
// undefined

盗用构造继承的优劣:

  • 优势:子类可继承父类的实例属性和方法同时子类在实例化时可以给父类的构造函数传参

  • 劣势:无法继承父类原型链上的属性和方法

3.3 组合继承(原型链 + 盗用构造函数)

组合继承(也称伪经典继承)综合了原型链和盗用构造函数,将两者的优点集中了起来。基本的思想就是使用原型链继承原型链上的属性和方法,而通过盗用构造函数继承实例属性。这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。

// 3. 原型链 + 盗用构造函数 实现组合继承(也称伪经典继承)
// 原型链继承原型链上的属性和方法
// 盗用构造函数继承实例属性和参数的传递
function Man(...args) {Person.call(this, ...args)
};Man.prototype = new Person();const love = new Man('love', 18);
console.log('\nlove-----------------------------------------');
console.log(love.name, love.age, love.star);    // love 18 Earth 可获取到父类的实例属性以及参数传递
love.init();    // love is fighting: 18!  可获取父类的实例方法以及参数传递console.log(love.nationality);    // [ 'China' ] 可获取到父类的原型链属性
love.home();    // love's home is in Earth  可获取到父类的原型链方法

4. 总结

有时有趣,有时烦躁,学习这样的知识点需要静下心来,一点一点的啃,反复琢磨。

《红宝书4》P238 详细的介绍了继承,更多详细的细节可到书中查看。
在这里附上完整code吧!

// ES5 类
// 构造函数方式实现类
function Person(name, age) {// 实例属性,只能实例使用,构造函数获取不到this.name = name;this.age = age;   this.star = 'Earth'; // console.log(Person.star);  undefined// 实例方法,也只能实例使用this.init = function() {console.log(`${this.name} is fighting: ${this.age}!`);};
};
// 原型链属性,可被多个实例共享, 也只能实例使用
Person.prototype.nationality = ['China'];   // console.log(Person.nationality); undefined
// 原型链方法
Person.prototype.home = function() {console.log(`${this.name}'s home is in ${this.star}`);
};// 静态属性,实例无法获取, 只能构造函数本身使用
Person.universe = 'TheMilkyWay';    // console.log(arrow.universe); undefined
// 静态方法
Person.shuttle = function() {console.log('shuttling');
};// ES5 继承
// 1. 原型链继承,可以继承父类的实例属性和方法以及父类原型链上的属性和方法,但是子类在实例化时不能给父类的构造函数传参
function Man_1() {};
Man_1.prototype = new Person();const bullet_1 = new Man_1();
console.log('bullet-1-----------------------------------------');
console.log(bullet_1.star);   // Earth 可以获取到父类的实例属性
console.log(bullet_1.nationality);   // [ 'China' ] 可以获取到父类原型链上的属性
bullet_1.init();    // undefined is fighting: undefined!  可以使用父类的实例方法,但是没有参数传递
bullet_1.home();    // undefined's home is in Earth  可以使用父类的原型链上的方法,但是没有参数传递
// Earth
// [ 'China' ]
// undefined is fighting: undefined!
// undefined's home is in Earth// 2. 盗用构造函数(constructor stealing, 也称对象伪装或者经典继承)继承,子类可继承父类的实例属性和方法同时子类在实例化时可以给父类的构造函数传参,但是无法继承父类原型链上的属性和方法
function Man_2(...args) {Person.call(this, ...args)
};const bullet_2 = new Man_2('bullet', 32);
console.log('\nbullet-2-----------------------------------------');
console.log(bullet_2.name, bullet_2.age, bullet_2.star);   // bullet 32 Earth 可以获取到父类的实例属性,并且可以传递参数
bullet_2.init();  // bullet is fighting: 32! 可以获取到父类的实例方法,并且可以传递参数console.log(bullet_2.nationality);  // undefined 无法获取到父类原型链上的属性, 自然方法也获取不到// bullet 32 Earth
// bullet is fighting: 32!
// undefined// 3. 原型链 + 盗用构造函数 实现组合继承(也称伪经典继承)
// 原型链继承原型链上的属性和方法
// 盗用构造函数继承实例属性和参数的传递
function Man(...args) {Person.call(this, ...args)
};Man.prototype = new Person();const love = new Man('love', 18);
console.log('\nlove-----------------------------------------');
console.log(love.name, love.age, love.star);    // love 18 Earth 可获取到父类的实例属性以及参数传递
love.init();    // love is fighting: 18!  可获取父类的实例方法以及参数传递console.log(love.nationality);    // [ 'China' ] 可获取到父类的原型链属性
love.home();    // love's home is in Earth  可获取到父类的原型链方法
http://www.lbrq.cn/news/2746765.html

相关文章:

  • 网站设计与网页制作在线企业信息查询
  • 武汉网站设计公司排名新站快速收录
  • 游戏开发有前途吗seo培训机构排名
  • 成都电商app开发seo同行网站
  • 网站制作创业磁力狗在线
  • 医疗机械网站怎么做哪个合肥seo好
  • 做网站银川快推达seo
  • 高端网站建设服务商外贸网站推广怎么做
  • 日本真人做爰无遮挡视频免费网站网站推广策划报告
  • 深圳网站建公司天津疫情最新消息
  • 辽宁手机版建站系统开发网站的推广方式
  • 动态网站开发 用什么模板语言企业管理
  • 沈阳专业网站制作设计淘宝的关键词排名怎么查
  • 做自己的博客网站网销怎么销售的
  • 外贸网站建设软件网络营销品牌公司
  • wordpress超链接出错谷歌seo最好的公司
  • 长沙网站建seo营销外包
  • 迪奥官网网站做的好吗在线一键免费生成网页网站
  • 网页制作技术基础教程seo推广哪家公司好
  • 网站的产品中心怎么做北京seo排名技术
  • 网站备案证书如何打开年轻人不要做网络销售
  • 做dnf辅助网站网站怎么添加外链
  • 农业网站建设方案 ppt模板下载产品关键词
  • 网站投放广告教程深圳全网营销平台排名
  • 域名138查询网seo优化师是什么
  • 网站服务器租用需要什么材料双11各大电商平台销售数据
  • 超级优化还原怎么快速优化网站
  • 他们怎么做的刷赞网站网络营销职业规划300字
  • 湖北阳新县建设局网站百度竞价推广代运营
  • 临夏金属装饰网站建设怎么申请建立网站
  • Spring 创建 Bean 的 8 种主要方式
  • React 基础实战:从组件到案例全解析
  • 【编程实践】关于S3DIS数据集的问题
  • linux中已经启用的命令和替代命令
  • Python异常、模块与包(五分钟小白从入门)
  • 【开发技巧】VS2022+QT5+OpenCV4.10开发环境搭建QT Creator