前两天说明面向对象的三大特性及JS不符合面向对象,只能称作支持面向对象而已,今天我们来看看JS的原型继承。

首先我们先来看,什么是原型(vmwork):

两个物件之间的原型关系(prototype relationship)跟继承(inheritance)有关:

每个物件都可以有另一个物件作为它的原型(prototype),如此一来,前者就会继承其原型的所有特性。

一个物件藉由内部特性(property)[[Prototype]]来指定其原型。

每个物件都有这个特性,但它可能是null。由[[Prototype]]连接起来的物件串链(chain of objects)被称作原型串链(prototype chain)。

《Speaking JavaScript第十七章-物件与继承》

我相信第一次看到这段话的人肯定是满脸问号,我也是一样。

![](https://i.imgur.com/SDkfh9b.png =200x)

没关系我们一步一步慢慢来看!

简单来说,可以定义一些自动成为可让其它物件存取的属性和功能

在JS中,我们可以很容易的建立一个物件,也可以轻易的修改和删除已经指派给物件的属性。

var obj = {

a:'apple',

b:function(){},

c:{},

d:[]

};

obj.a = [];

obj.b =“banana”;

delete obj.c;

在开发过程中,我们都会尽量避免重复造轮子,也就是尽可能的重复利用现有的代码。

所以一种可重复利用的代码,并帮助我们把程序组织好的方式就是「继承」,把存在于某个物件上的功能延伸到其他物件上。

在JS中,继承就是用「原型」实作出来的。

透过原型,物件可以存取属于其他物件的属性

const Jason = {

CSS:true

};

const Turtle = {

JS:true

};

const Kai = {

Vue:true

};

我们刚刚建立了三个物件,每个物件都有一个自己才能存取的属性。

可以利用in测试物件能否存取某个属性:

“JS”in Jason;//false

“CSS”in Jason;//true

如果我们想要Json存取Turtle的JS属性,可以用Object.setPrototypeOf,需要两个参数(argument),并把第二个参数设为第一个参数的原型,所以我们可以这样做:

Object.setPrototypeOf(Jason,Turtle);

“JS”in Jason;//true

现在我们可以透过Jason存取JS属性了,这是因为每当像Jason存取JS时,便会在物件原型里搜寻该属性,因为我们已经让Jason继承了Turtle让它成为其原型,所以可以存取Turtle的属性。

在JS中,物件原型是物件的内部属性,无法直接存取,所以会标示为[[Prototype]]。

那如果我们想要Jason也能存取Kai的属性,相信很多人会直接这样写:

Object.setPrototypeOf(Jason,Kai);

“JS”in Jason;//false

“Vue”in Jason;//true

Jason的确可以存取Kai的属性了,但同时Kai也取代了Turtle成为了它的原型(leafor)。

那我们该怎么做呢?我们前面有提到过「每个物件都有[[Prototype]]特性可以来来指定其原型。」,所以Turtle成为Jason原型后,也可以指定Kai当作其原型,这个行为称为「原型串链(prototype chain)」。

Object.setPrototypeOf(Jason,Turtle);

Object.setPrototypeOf(Turtle,Kai);

“JS”in Jason;//true

“Vue”in Jason;//true

可以看到说Jason已经可以顺利存取Turtle及Kai的属性了!

那么,今天就到这边,一样如果有错误及来源未附上也欢迎留言指正,那么我们明天见。

学JS的心路历程-物件与原型(一)的更多相关文章

  1. 学JS的心路历程 -物件与原型(二)

    昨天有提到说Object.setPrototypeOf可以指定一个物件为另一个物件的原型,但有想过到底这个原型,也就是[[Prototype]]最终会到何处吗? 答案是Object.prototype ...

  2. 学JS的心路历程-物件与原型(三)

    昨天有说明到函式与建构式的原型,及指定建构式函式原型为另一个建构式函式,但其实这会造成复写constructor的问题. 复写constructor的问题(vmwork) 我们昨天有提到「建构式函式可 ...

  3. 学JS的心路历程 - JS的Class

    没错,你没有看错,虽然前面说JS是原型继承,但在ES6以后新增了class关键字!!! 不过底层实作仍然是以原型继承方式进行,所以基本上算是一个语法糖. 今天我们就来看一下如何使用吧! class 首 ...

  4. 学JS的心路历程-JS支持面向对象?(二)

    昨天讲了面向对象的继承,今天我们来谈谈多态和封装吧! 多态polymorphism 抽象讲法解释,就是使用单一界面操作多种型态的物件 继承父类别,定义与父类别中相同的方法,但实作内容不同,称为复写(o ...

  5. 学JS的心路历程-JS支持面向对象?(一)

    昨天在看Prototype看到JS支持面向对象,被前辈问到说那什么是面向对象?JS是面向对象语言吗? 便开始了一连串艰辛爬文过程,今天就来看一下两者有什么差异吧(rgwyjc)! 首先面向对象有三大特 ...

  6. 学JS的心路历程-for of和for in

    我们在刚入门JS时候,说到要跑出数组的每个值肯定都是这样子: var arr = [1,2,3,4,5,6]: for(let i = 0:i < arr.length:i++){ consol ...

  7. 学JS的心路历程 -函式(三)this

    this是什么,取决于被呼叫的呼叫地点. 昨天有提到说,呼叫函式时候会传递隐含参数:arguments和this并讲解了arguments,今天我们就来探讨this吧! 什么是this 我们都会呼叫函 ...

  8. 学JS的心路历程Day26 - PixiJS -入坑

    后来知道也可以透过canvas让网页动起来! 而PixiJS是使用WebGL在canvas上绘制内容与制作动态 且同时有下列特色: 支持多点触控 掩码与混合模式 可外加WebGL滤镜 多装置支持 等等 ...

  9. 学JS的心路历程-Promise(三)

    今天我们来说then一些特殊情况以及Promise.all()与Promise.race(). 我们都知道函式作为参数传入时,可以参照的方式传入,也能传入时执行拿回传值作使用: function us ...

随机推荐

  1. CVPR 2019 | 用异构卷积训练深度CNN:提升效率而不损准确度

    对于深度卷积神经网络而言,准确度和计算成本往往难以得兼,研究界也一直在探索通过模型压缩或设计新型高效架构来解决这一问题.印度理工学院坎普尔分校的一篇 CVPR 论文则给出了一个新的思路——使用异构的卷 ...

  2. Android WebView无法播放视频或直播,关闭界面后任在播放的问题;

    1.设置webview属性: webView.setWebChromeClient(new MyWebChromeClient());         webSettings = webView.ge ...

  3. IIS7.5和IIS8如何设置FTP的pasv端口范围

    如果不设置端口范围,在防火墙开启的情况下,连接FTP时可能出现列表错误的现象,下面介绍下如何设置FTP的pasv端口范围.. 一.首先打开IIS选择服务器会进入全局设置,再双击FTP防火墙支持 二.设 ...

  4. JavaScript基础知识:数据类型,运算符,流程控制,语法,函数。

    JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...

  5. ELK集群部署实例(转)

    转载自:http://blog.51cto.com/ckl893/1772287,感谢原博. 一.ELK说明 二.架构图 三.规划说明 四.安装部署nginx+logstash 五.安装部署redis ...

  6. Linux 虚拟机VMware安装失败,提示没有选择磁盘

    提示安装位置:没有选择磁盘 磁盘类型问题. 在新建虚拟机向导时会推荐选项 重新安装就有磁盘了

  7. angularjs探秘<五> 举足轻重的scope

    scope在angular中的作用可谓举足轻重,不理解scope就不会angular: scope是应用在 HTML (view) 和 JavaScript (controller)之间的纽带. sc ...

  8. 初窥GPFS文件系统(转)

    原文地址:http://blog.csdn.net/jznsmail/article/details/5502840?reload 本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化 ...

  9. linux 查看磁盘空间

    linux 查看磁盘空间大小命令 df :命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息 df -hl:查看磁盘剩余空间信息,显示如下: 文件系统          ...

  10. 1. ibatis 查询的sql列存在相同的列名

    如果SQL语句存在两个相同的查询列名,则映射时,取第一个列名的值进行映射 <?xml version="1.0" encoding="UTF-8" ?&g ...