javascript 本地对象和内置对象_详解 JavaScript 面向对象

28d3309f950e128a4df75e9d52c10f9f.png

1. 概述

JavaScript面向对象比较难理解的点是类的继承。不管是es5写法还是es6写法,JavaScript继承的本质是原型链。具体可看我的上一篇文章:

田浩:详解原型、原型链、构造函、实例、new​zhuanlan.zhihu.com
dea03a15090578781e476008350c9f8e.png

因为es6有专门的语法,写法很简单且容易理解,所以本文将着重介绍es5的实现继承不同方式及其原理。

再阅读本文之前,一定要注意区分几个名词:父类、子类、子类的实例。


2.类的声明和实例化:

/*** 类的声明*/
var Animal = function () {this.name = 'Animal';
};/*** es6中class的声明*/
class Animal2 {constructor () {this.name = 'Animal2';}
}/*** 实例化方式相同*/
let dog = new Animal();
let dog2 = new Animal2();

2. ES5中类的继承:

2.1 借助构造函数实现继承(部分继承)

function Parent1 () {this.name = 'parent1';
}Parent1.prototype.say = function () {
};      // 不会被子类继承function Child1 () {Parent1.call(this);this.type = 'child1';
}   

原理:

核心在于:Parent1.call(this)

改变Parant1运行时的this的指向,指向子构造函数,所以父类中有的属性,子类中也有。

缺点:

父类原型链上的属性方法并没有被子类继承。 所以这种方式不能成为继承,只能叫做部分继承。

2.2 借助原型链实现继承

function Parent2 () {this.name = 'parent2';this.array = [1,2,3];
}
function Child2 () {this.type = 'child2';
}
Child2.prototype = new Parent2();

原理:

核心在于: Child2.prototype =new Parent2();

将Parent2的一个实例作为Child2的prototype。访问Child2的实例时候,实例可以通过__proto__访问Parent2中的属性。

缺点:

试想,如果Child2实例两个对象s1、s2,他们通过__proto__访问的父类上的属性实际上是同一个引用(s1.__proto__ === s2.__proto__)。这样,比如s1修改array,s2的array也会跟着变。这是我们所不想看到的。

2.3 组合方式

将上两种组合:

function Parent3 () {this.name = 'parent3';this.array = [1, 2, 3];
}
function Child3 () {Parent3.call(this); this.type = 'child3';
}
Child3.prototype = new Parent3();

原理:

核心在于: 将上两种方式结合。实际上,子类的实例中,Parent3上的属性会存在两份,一份在实例中,一份在实例的__proto__上:

1c6cee89fe02859c621aa9772a18c27e.png

缺点:

实例化子类的时候,父类执行了两次,且子类实例中存在冗余数据。这些都是没有必要的。

2.4 组合继承的优化1

function Parent4 () {this.name = 'parent4';this.play = [1, 2, 3];
}
function Child4 () {Parent4.call(this);this.type = 'child4';
}
Child4.prototype = Parent4.prototype;

原理:

核心在于: 将 Parent4的prototype直接赋给Child4.prototype。此时父类只执行一次。

af17c36a539014af380e66dbe2518fe7.png

缺点:

子类实例的constructor会指向父类:a的constructor会指向Parent4,不符合预期,无法区分这个实例是父类创造的还是子类创造的。当然这个缺点在2.3中也存在。原因是constructor属性来自原型对象中,上述方法子类的实例访问constructor 实际访问的事父类的prototype中的constructor。

2.5 组合继承的优化2

function Parent5 () {this.name = 'parent5';this.play = [1, 2, 3];
}
function Child5 () {Parent5.call(this);this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype);
// 手动修改constructor指向,由于父类的prototype和子类的prototype已经隔离开,可以放心修改。
Child5.prototype.constructor = Child5;

原理:

核心在于: Object.create(Parent5.prototype);

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

Object.create()​developer.mozilla.org
244ab3dcc27b0a9273904db2f9950afa.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android wifi设备连接通信,通过wifi与设备进行通信(Android)

通过wifi与设备进行通信(Android)[复制链接]本帖最后由 灞波儿奔 于 2019-2-17 21:40 编辑通过wifi与设备进行通信(Android)最近leader决定把app与设备之间的通信改为wifi,通过http协议实现设备之间的通信。相对与之前的蓝牙通信,的确简单不少&#xff0…

工作汇报ppt案例_【赠书】开工大吉!今年一定要干过写PPT的!

不知不觉,春节就过去了,新年开工,朋友圈里晒满了开工红包,领了开工礼就意味着真正新的一年开始了。虽然假期的慵懒安逸留下了倦怠的后遗症,但状态依旧切换到工作模式,毕竟每年都希望能比过去更进一步&#…

android webview 长按复制,Android webview 点击或长按有蒙层 – 热爱改变生活

Android 使用 webview 加载本地 html,在本地 html 上面点击的时候会有一层橙色的蒙层,使用下面的代码可以去掉。body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquo…

postscript打印机什么意思_涨知识|你不知道的关于打印机的打印过程和打印机驱动的那些事...

以前一直以为打印很简单,不就是编辑好文件按个“打印”就行了?但其实打印过程可以复杂到你分分钟“怀疑人生”。你以为的打印过程可能是这样的 ↓。我们看到的打印过程然而,真正的打印过程是这样的 ↓。实际上的打印过程打印机打印一页文件或…

python dicom图像分割_python读取DICOM头文件的实例

这篇文章主要介绍了关于python 读取DICOM头文件的实例,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 用dicompyler软件打开dicom图像,头文件如图所示:当然也可以直接读取: ds dicom.read_…

索尼android电视图片轮播,电视投屏居然还能这样玩?

原标题:电视投屏居然还能这样玩?现如今,投屏几乎成为大家日常生活必不可少的一种观影方式,通过电视投屏可以带来更清晰的画面效果,成为追剧党以及各类球赛爱好者的不二之选。那么今天小智就以索尼电视为例,…

python源码多平台编译_提升Python程序运行效率的6个方法

Python是一个很酷的语言,因为你可以在很短的时间内利用很少的代码做很多事情。不仅如此,它还能轻松地支持多任务,比如多进程等。Python批评者有时会说Python执行缓慢。本文将尝试介绍6个技巧,可加速你的Python应用程序。 1.让关键…

android 高并发弹幕,高并发实时直播弹幕研发实践

高并发实时直播弹幕研发实践直播间特点聊天室限制人数的原因应对万级以上的实时互动跨服务器是为了解决单一服务器接入数量限制、发布消息吞吐限制等问题;多进程并发则是为了充分利用多核CPU以及减小一个循环规模从而达到降低延迟的目的。云巴实时系统的设计云巴是基…

linux python3_在Linux上安装Python 3

在Linux上安装Python 3这份文档描述了如何在Ubuntu Linux机器上安装Python 3.6。 想要获取已安装的Python 3版本号,可以通过终端运行命令: $ python3 --version 如果您使用的是Ubuntu 16.10或更新,可以通过以下命令简单地安装Python 3.6: $ s…

android手机电话铃声设置,安卓手机铃声怎么设置

网上有很多安卓手机铃声的设置教程,说什么SD卡里建立这个那个的文件夹,那问题是怎么才能进到SD卡里去建立文件夹啊?手机里哪个选项里进去呢?这里小编告诉你,可以通过电脑连接数据线管理SD卡。下面介绍两种简单的设置安…

安装squid_「首席推荐」设置Squid转发代理或者正向代理

如果您正在阅读这篇文章,您可能会因为缺少与Squid相关的信息而感到沮丧,Squid是一种非常流行的转发代理。这些令人沮丧的事情包括:在小的软件修订之后出现的重大的可用性变化,对幕后发生的事情的误解,以及真正糟糕的文档。这是一个…

android压缩图片质量,Android 图片质量压缩有关问题

Android 图片质量压缩问题本帖最后由 u013064347 于 2014-01-13 10:22:47 编辑网上看到一个图片质量压缩法,传入1M以内图片能正常压缩,但是传入2M多的图片就报内存溢出,应该怎么解决?附上代码Bitmap imagesBitmapFactory.decodeFi…

python标准库os_Python基础--人们一些最爱的标准库(sys os fileinput)

这篇博客就介绍介绍常见的、人们钟爱的python中的标准库。 sys 从字面上也能看出来,是system的缩写。这个模块能够访问与python解析器紧密联系的变量和函数。 argv 命令行参数 exit 退出当前程序 modules 映射模块名到载入模块的字典 path 目录 platform 平台标识符…

android区域截图app,【干货】最新App应用市场截图尺寸大全

今天给大家分享最新的干货,刚好碰上这段时间设计市场截图,所以给各位设计新人,分享本人整合的尺寸大全,希望对你们的设计之路有所帮助。一、IOS App Store尺寸尺寸(机型) 大小(px)3.5寸(iphone4/4s)…

python如何运行一个python程序_在python中,如何运行一个命令行程序,它在发送Ctrl+D之前不会返回...

由于没有人提供任何代码来帮助解决这个问题,我将做如下的事情。结果发现pexpect非常强大,而且您不需要signal模块。在import os import sys import pexpect def run_server(): server_dir /path/to/server/root current_dir os.path.abspath(os.curdir…

android app外唤起,Android 唤起app的多种方式

方式一(通过Intent唤起):我们自己的app代码:ComponentName componetName new ComponentName("com.lh.jimtrency.webviewdemo","com.lh.jimtrency.webviewdemo.MainActivity");//(另外一个应用程序的包名,要启动的Activi…

2018python做图形界面哪个库简单_2018年常见的python编程开发库都有哪些类型

python编程开发可以说是目前比较热门的一项编程开发语言了,而今天我们就一起来了解一下,关于python编程都有哪些常见的python库可以使用。1、TensorFlow “TensorFlow是一个使用数据流图进行数值计算的开源软件库。图形节点表示数学运算,而图…

android条形图,MPAndroid组条形图未显示

这个问题已经在这里有了答案:????????????>????????????How to check if activity is in foreground or in visible background?????????????????????????????????????22个这是我用于使用MPAndroi…

c++ socket线程池_java 网络编程,Socket编程

Java的网络编程主要涉及到的内容是Socket编程,那么什么是Socket呢?简单地说,Socket,套接字,就是两台主机之间逻辑连接的端点。TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应…

android签名忘记密码,修改Android签名证书keystore的密码、别名alias以及别名密码

之前在测试Eclipse ADT的Custom debug Eclipse ADT的Custom debug keystore所需证书规格,提到过自定义调试证书的密码和1. 首先当然是先复制一份正式证书出来作为要修改为的临时调试证书。2. 修改keystore密码的命令(keytool为JDK带的命令行工具):keytoo…