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

答案是Object.prototype!

Object.prototype

在第一天有提到说「JS中除了原始型别以外的一切都是物件」。

所以每条正常的[[Prototype]]串链最顶层的尾端都是内置的Object.setPrototypeOf,这个物件含有JS中各地方所用的常见工具,如toString()、hasOwnProperty()、valueOf()等等,所有正常的物件都应起源于这个Object.setPrototypeOf物件(vmwork)。

建构式与原型

在第八天时,有提到说建构式会经由new呼叫函式,建立一个新的物件:

function Foo(){

this.say =“hello”;

}

var a = new Foo();

但其实new Foo()产生一个新的物件a同时,新的物件a的内部会有[[Prototype]]连接至Foo.prototype。

等等,Foo.prototype的.prorotype是什么鬼东西?函式有自己的原型?

「每一个函式都有一个原型物件,会被自动设为透过该函式所建立的物件原型」。

也就是说prototype是当用new创建新的物件时,该新物件的[[Prototype]]。

那我们要怎么看一个物件的原型呢?可以用__proto__或Object.getPrototypeOf()。

function Foo(){

this.say =“hello”;

}

var a = new Foo();

a.__proto__;//{constructor:ƒ}

Object.getPrototypeOf(a);//{constructor:ƒ}

Object.getPrototypeOf(a)=== Foo;//false

Object.getPrototypeOf(a)=== Foo.prototype;//true

用图表来看可能会比较好理解。

好,又有一个奇怪的东西了,什么是constructor?

函式的原型物件也就是Foo.prototype会具有constructor的属性,会参照回原来的函式。

我们建立出来的新物件,其原型会被设定为建构式函式原型所参照的物件,可以透过.constructor来存取建立物件的函式以此来作类型检查。

function Foo(){

this.say =“hello”;

}

var a = new Foo();

typeof a;//“object”

a instanceof Foo;//true

a.constructor === Foo;//true

a.__proto__.constructor === Foo;//true

所以我们可以用这张图来表示。

使用原型来实现继承

函式原型是一个物件,所以在继承实有许多种复制功能的方式。

function Person(){};

Person.prototype.say =“Hi”;

function trickyMan(){};

trickyMan.prototype = { say:Person.prototype.say};

var Jason = new trickyMan();

Jason instanceof trickyMan;//true

Jason instanceof Person;//false

执行后发现没有办法把Person继承trickyMan,这只是复制而已。

如果想要真正的原型串链,也就是Jason可以是trickyMan,trickyMan可以是Person,一直到最终的Object,应该这样做:

function Person(){};

Person.prototype.say =“Hi”;

function trickyMan(){};

trickyMan.prototype = new Person();

var Jason = new trickyMan();

Jason instanceof trickyMan;//true

Jason instanceof Person;//true

要注意到的是,由于把trickyMan指定为Person的建构物件,所以trickyMan的原本的constructor没有被任何东西参考,会被弃置且删除。

我们来看一下图片(leafor)。

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

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

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

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

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

    前两天说明面向对象的三大特性及JS不符合面向对象,只能称作支持面向对象而已,今天我们来看看JS的原型继承. 首先我们先来看,什么是原型(vmwork): 两个物件之间的原型关系(prototype r ...

  3. 学JS的心路历程-函式(二)arguments

    参数(argument)与函式参数(parameter) 在讨论函式时,很多人都会把这两个搞混,我自己也不例外. 虽然讲错别人也听得懂,但是我们还是要搞清楚这两个的定义到底是什么! 参数是当我们呼叫函 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 05-spark streaming & kafka

    1.如何消费已经被消费过的数据? 答:采用不同的group 2.如何自定义去消费已经消费过的数据? Conosumer.properties配置文件中有两个重要参数 auto.commit.enabl ...

  2. 函数的嵌套+nonlocal和global关键字(重点)

    1.在函数中声明函数 在内部函数中使用变量的时候, 查找顺序: 先找自己 -> 上一层 -> 上一层..全局 -> 内置 # 函数的互相调用 # def func1(): # pri ...

  3. 利用Python实现FGO自动战斗脚本,再也不用爆肝啦~

    Fate/Grand Order(非的肝不过欧的)作为索尼为了拯救自己不倒闭而开发的面向月厨的骗氪养成抽卡爆肝游戏,居然没有像隔壁<阴阳师>的自动战斗系统(看看别人现在都自带脚本了).毕竟 ...

  4. 将mysql数据库数据以Excel文件的形式导出

    最近在工作中,领导让从数据库中导出一些数据并存放到Excel表格中,网上有许多教程,下面是我总结的其中俩种方法. 从数据库管理工具中导出(navicat) 在navicat导出数据导Excel中还是比 ...

  5. 普通rgb转换为16进制

    http://www.zhangxinxu.com/study/201003/color-exchange-test.html

  6. SLD Related Gateway Serivces Unavaliable

    SAP NW 7.4 default switched on the ACL (access control list) in gateway service, so only local acces ...

  7. zookeeper(3) zookeeper的实践及原理

    一.基于java API初探zookeeper的使用 (1)建立连接 public static void main(String[] args) { //NOT_CONNECTED-->CON ...

  8. OpenCV:直线拟合——cv::fitLine()详解

    实现目的:有一系列的点,需要拟合出一条直线. cv::fitLine()的具体调用形式如下: void cv::fitLine( cv::InputArray points, // 二维点的数组或ve ...

  9. MySQL 5.7.20 ONLY_FULL_GROUP_BY

    < SQL_MODE 的配置方式 > 01,默认情况下 5.7.20 MySQL 开启该模式,我们可以用指 SQL 预计查看 => select @@global.sql_mode; ...

  10. linux常用工具及命令

    1.windows复制文件到linux可以使用工具winscp工具 2.建立软连接命令(将/software/run.log的文件指向/usr/local/logs/中): cd /usr/local ...