首页 web前端 js教程 为什么需要利用javascript实现继承?几种继承方式实例详解

为什么需要利用javascript实现继承?几种继承方式实例详解

Jul 20, 2017 pm 03:55 PM
javascript js 为什么

为何需要利用javascript实现继承

早期pc机器的性能确实不敢恭维,所有的压力全在服务器端,客户端浏览器纯属摆设。再加上那时流行的table布局以及电话线的上网方式导致浏览一个网页十分的卡;而今互联网时代飞速发展,个人电脑硬件得到了极大提升,客户端浏览器的性能也十分的酸爽,web开发的模式也在悄悄改变:服务端不再像以前那样“辛苦”,取而代之的是尽可能的让浏览器承担更多的任务,如此一来,压力分摊到每个客户端上,企业不但节省成本,随之也让web前端开发变的更加有趣--越来越多的前端框架层出不穷,甚至出现了许多前端的MVC框架。在这种背景下,javascript的角色已经绝对不是只做一些简单的验证,发送一些请求或者操作一些DOM,更多的需要担任类似前端路由和业务层的角色,并且javascript需要做大量的逻辑性任务,这里面就包括前台数据的抽离(即model),而只有运用面向对象的思维才能很好的对抽离数据进行处理,因此继承就在这里显得举足轻重。

现从前台抽离一个model名为Person,其有基本属性name和age,默认每个人都会说话,因此将说话的功能say放在了原型对象上,以供每个实例享用。现在对于Man来说,它需要继承Person的基本属性,并且在此基础上添加自己特有的属性。


function Person (name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
  console.log('hello, my name is ' + this.name);
};
function Man() {
  //my own properties
}
登录后复制

几种主流的继承方式:

1.原型链继承


function Person (name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
  console.log('hello, my name is ' + this.name);
};
function Man() {
}
Man.prototype = new Person('pursue');
var man1 = new Man();
man1.say(); //hello, my name is pursue
var man2 = new Man();
console.log(man1.say === man2.say);//true
console.log(man1.name === man2.name);//true
登录后复制

这种继承方式很直接,为了获取Person的所有属性方法(实例上的和原型上的),直接将父类的实例new Person('pursue')赋给了子类的原型,其实子类的实例man1,man2本身是一个完全空的对象,所有的属性和方法都得去原型链上去找,因而找到的属性方法都是同一个。
所以直接利用原型链继承是不现实的。

2.利用构造函数继承


function Person (name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
  console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
  Person.apply(this, arguments);
}
//Man.prototype = new Person('pursue');
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
man1.say(); //say is not a function
登录后复制

这里子类的在构造函数里利用了apply去调用父类的构造函数,从而达到继承父类属性的效果,比直接利用原型链要好的多,至少每个实例都有自己那一份资源,但是这种办法只能继承父类的实例属性,因而找不到say方法,为了继承父类所有的属性和方法,则就要修改原型链,从而引入了组合继承方式。

3.组合继承


function Person (name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
  console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
  Person.apply(this, arguments);
}
Man.prototype = new Person();
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
console.log(man1.say === man2.say);//true
man1.say(); //hello, my name is joe
登录后复制

需要注意的是man1和man2的实例属性其实是覆盖了原型属性,但是并没要覆盖掉原型上的say方法(因为它们没有),所以这里man1.say === man2.say依然返回true,因而需要十分小心没有覆盖掉的原型属性,因为它是所有实例共有的。

4.寄生组合继承

说实话真不知道下面的这种形式叫这名字,但是它确实是最流行,最经典的javascript的继承方式。其实,只需要明白原型对象的结构即可:


function Person (name, age) {
      this.name = name;
      this.age = age;
    }
Person.prototype.say = function(){
  console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
  Person.apply(this, arguments);
}
Man.prototype = Object.create(Person.prototype);//a.
Man.prototype.constructor = Man;//b.
var man1 = new Man('pursue');
var man2 = new Man('joe');
console.log(man1.say == man2.say);
console.log(man1.name == man2.name);
登录后复制

其实寄生组合继承和上面的组合继承区别仅在于构造子类原型对象的方式上(a.和b.),这里用到了Object.creat(obj)方法,该方法会对传入的obj对象进行浅拷贝,类似于:


function create(obj){
  function T(){};
  T.prototype = obj;
  return new T();
}
登录后复制

因此,a.会将子类的原型对象与父类的原型对象进行很好的连接,而并不像一般的组合继承那样直接对子类的原型进行复制(如Man.prototype = new Person();),这样只是很暴力的在对属性进行覆盖。而寄生组合继承方式则对实例属性和原型属性分别进行了继承,在实现上更加合理。

注意:代码b.并不会改变instanceof的结果,但是对于需要用到construcor的场景,这么做更加严谨。

以上是为什么需要利用javascript实现继承?几种继承方式实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

H5页面制作是否需要持续维护 H5页面制作是否需要持续维护 Apr 05, 2025 pm 11:27 PM

H5页面需要持续维护,这是因为代码漏洞、浏览器兼容性、性能优化、安全更新和用户体验提升等因素。有效维护的方法包括建立完善的测试体系、使用版本控制工具、定期监控页面性能、收集用户反馈和制定维护计划。

为什么在Safari中自定义样式表能在本地网页生效,但在百度页面上却无法生效? 为什么在Safari中自定义样式表能在本地网页生效,但在百度页面上却无法生效? Apr 05, 2025 pm 05:15 PM

在Safari中使用自定义样式表的问题探讨今天我们来探讨一个关于Safari浏览器的自定义样式表应用问题。前端新手...

H5页面制作的优势有哪些 H5页面制作的优势有哪些 Apr 05, 2025 pm 11:48 PM

H5 页面制作的优势包括:轻量级体验,加载速度快,提升用户留存率。跨平台兼容性,无需针对不同平台适配,提升开发效率。灵活性和动态更新,无需审核,便于内容修改和更新。成本效益,开发成本比原生 App 低。

没有H5,JS能运行吗? 没有H5,JS能运行吗? Apr 06, 2025 am 09:06 AM

JavaScript 是否可在无 HTML5 环境下运行?JavaScript 引擎自身可独立运行。在浏览器环境中运行 JavaScript 依赖 HTML5,因其提供加载和执行代码所需的标准化环境。HTML5 提供的 API 和特性对现代 JavaScript 框架和库至关重要。离开 HTML5 环境,许多 JavaScript 功能难以实现或无法实现。

Bootstrap Table乱码与页面编码的关系 Bootstrap Table乱码与页面编码的关系 Apr 07, 2025 pm 12:03 PM

Bootstrap Table 乱码通常是因为页面编码与表格数据编码不一致。要解决此问题,需要确保它们一致,具体步骤包括:检查页面和表格数据编码,设置页面编码,验证编码。如果使用 UTF-8,服务器也应支持。无法解决时,可尝试使用 JavaScript 编码库。

为什么在element-plus项目中使用官网示例的类名样式没有效果? 为什么在element-plus项目中使用官网示例的类名样式没有效果? Apr 05, 2025 pm 07:27 PM

如何在element-plus中正确使用类名样式?在使用element-plus的过程中,很多开发者会遇到一个问题:为什么在自己的...

无法以 root 身份登录 mysql 无法以 root 身份登录 mysql Apr 08, 2025 pm 04:54 PM

无法以 root 身份登录 MySQL 的原因主要在于权限问题、配置文件错误、密码不符、socket 文件问题或防火墙拦截。解决方法包括:检查配置文件中 bind-address 参数是否正确配置。查看 root 用户权限是否被修改或删除,并进行重置。验证密码是否准确无误,包括大小写和特殊字符。检查 socket 文件权限设置和路径。检查防火墙是否阻止了 MySQL 服务器的连接。

See all articles