JavaScript原型链的一夜情

Stella981
• 阅读 587

△ 是新朋友吗?记得先点web前端学习圈关注我哦~

JavaScript原型链的一夜情

JavaScript原型链的一夜情

Brendan Eich(布兰登·艾奇) 作为JavaScript的作者曾说过 “它是C语言和Self语言一夜情的产物。”

是因为它借鉴了C语言的基本语法和Self语言的使用基于原型(prototype)的继承机制。

所以我们也经常可以看到JavaScript被描述为一种基于原型的语言,每个对象都有一个原型对象。

对象以它的原型作为模版、从原型上可以继承属性和方法。原型对象也是对象,也有它自己的原型对象,并从中继承属性和方法。

一层一层,以此类推……

如果你愿意一层一层的拨开我的心~

JavaScript原型链的一夜情

上面说的这种关系就是

原型链 prototype chain

本文力争用通俗易懂的语言(人话),来带大家搞懂原型对象、原型链。

1

函数和对象

首先我们先来看一下JavaScript中函数和对象的关系,这对我们理解原型链有很大的帮助。

你可能也会看到“JavaScript中万物皆对象”,这显然是错误的。

实际上在JavaScript中,有许多特殊的对象子类型,可以叫做复杂基本类型。

函数就是对象的一个子类型。

函数的本质就是对象。

但是为什么使用typeof进行类型检查的时候会有下面的结果呢?

var o = {};                 // 普通对象

JavaScript: 嘿,兄弟,我是一夜情的产物,不要要求太多!

在JavaScript中,检测对象类型时,强烈建议使用Object.prototype.toString方法。typeof的一些返回值在标准文档中并未定义,因此不同的引擎实现可能不同。

http://bonsaiden.github.io/JavaScript-Garden/zh/#types.typeof

回到正题,实际上,函数和对象没有本质的区别,函数是特殊的对象。

函数对象天生带有prototype属性,也就是每个函数在创建之后会天生拥有一个与之相关联的原型对象,这个原型对象中拥有一个constructor属性,该属性指向这个函数。

注意:

很多人认为新创建的函数对象身上除了prototype属性外

还有constructor这个属性

但是这里使用的constructor属性实际上是从原型链中获取的

即Function.prototype.constructor

备注:在ECMAScript标准中函数创建相关章节有这样一句话:NOTE A prototype property is automatically created for every function, to allow for the possibility that the function will be used as a constructor.

解释了给新创建函数添加prototype属性的意义在于便于该函数作为构造函数使用。

https://www.ecma-international.org/ecma-262/5.1/#sec-13.2

搞清楚了JavaScript中函数和对象的关系后,我们接下来看一看什么是原型对象。

2

原型对象

当构造函数被创建出来的时候,会默认关联一个Ojbect类型的新对象,这个对象就是当前构造函数的原型对象,构造函数的原型对象默认是一个空对象。

当然,构造函数创建出来的对象可以访问该构造函数原型对象的属性和方法。

// 1 声明构造函数Man

JavaScript原型链的一夜情

通过上面的代码和结果进行分析,我们可以得出构造函数、实例、原型对象三者之间的关系。

JavaScript原型链的一夜情

我们可以得出以下结论

1.构造函数Man可以通过prototype属性访问到它的原型对象

2.通过构造函数Man实例化出来的d可以通过__proto__属性访问到Man的原型对象

3.Man的原型对象可以通过constructor(构造器)属性访问其关联的构造函数

我们可以通过三种方式来访问原型对象

1.构造函数.prototype

2.实例对象.__proto__

3.object.getPrototypeOf(实例对象)

prototype 函数对象拥有的属性,指向它的原型对象

__proto__ 所有的对象都拥有__proto__属性,指向实例的原型

construtor 构造器,原型对象可以通过constructor来访问其所关联的构造函数。当然,每个实例对象也从原型中继承了该属性。

注意:

__proto__属性并不在ECMAScript标准中,只为了开发和调试而生,不具备通用性, 不能出现在正式的代码中。

搞清楚了原型对象,接下来我们来看原型链。

3

原型链

function Man () {};

JavaScript原型链的一夜情

这一夜,原型链没少折腾...

// 1.让我们先来看一看食物链(原型链)的顶端 null

4

原型链的访问规则

就近原则

对象在访问属性或方法时,先检查自己的实例,如果存在就直接使用。如果不存在那么就去原型对象上去找,存在就直接使用,如果没有就顺着原型链一直往上查找,找到即使用,找不到就重复该过程直到原型链的顶端,如果还没有找到相应的属性或方法,就返回undefined,报错。

5

三种检验方法

Object.getPrototypeOf方法用于获取指定实例对象的原型对象。

function Demo(){};

isPrototypeOf方法用于检查某对象是否在指定对象的原型链中。

function Demo(){}

instanceof运算符的作用跟isPrototypeOf方法类似,左操作数是待检测的实例对象,右操作数是用于检测的构造函数。如果右操作数指定构造函数的原型对象在左操作数实例对象的原型链上面,则返回结果true,否则返回结果false。

// 1 声明构造函数Demo

注意:不要错误的认为instanceof检查的是该实例对象是否从当前构造函数实例化创建的,其实它检查的是实例对象是否从当前指定构造函数的原型对象继承属性。

6

最佳的组合继承方案 

思路

1.使用原型链实现对原型属性和方法的继承

2.通过伪造(冒充)构造函数来实现对实例成员的继承,并且解决了父构造函数传参问题

// 1 提供超类型|父类型

参考文顶顶的博客

http://wendingding.com/2018/04/15/javaScript系列%20\[04\]-javaScript的原型链/

感谢 · 转发欢迎大家留言

JavaScript原型链的一夜情

本文分享自微信公众号 - web前端学习圈(web-xxq)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
Vue+Electron从零开始打造一个本地播放器
△是新朋友吗?记得先点web前端学习圈关注我哦~!(https://oscimg.oschina.net/oscnet/fa62135a72114615886ea5ac626cb09e.jpg)!(https://oscimg.oschina.net/oscnet/1d12e085b28e447192624d388b
Stella981 Stella981
3年前
CSS八种让人CSS八种让人眼前一亮的HOVER效果眼前一亮的HOVER效果
△是新朋友吗?记得先点web前端学习圈关注我哦~!(https://oscimg.oschina.net/oscnet/59e0fdcce9194c1dbba02b7f73cc0275.jpg)一.发送效果HTML<divid"sendbtn"
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这