javaScript(原型链)
在了解javaScript的原型链之前,我们得先来看一下原型是什么。
在javaScript中,所有的函数都会有着一个特别属性:prototype(显示原型属性);当我们运行如下代码时:
function Fn(){
}
在内存中则是如下这样工作的:

我们可以看到,当function对象创建时,其会有一个属性:prototype,该属性在定义函数的时候被自动赋值,值默认为:{},即:指向堆空间中的空的object对象,而该object空对象即是此function的原型对象。
在函数实例化对象时,所有的实例化对象也会有一个特别的属性:__proto__(隐式原型属性),继续刚才的例子,我们运行如下代码:
function Fn(){
}
var fn=new Fn();
此时内存中是如下状况:

此时有没有发现function对象的显示原型属性与其实例化得到的对象的隐式原型属性的值是相同的,即它们指向同一个对象——空object(function的原型对象)。
下面我们来说下显示原型属性与隐式原型属性的关系。
在function实例化对象时,在其实例化对象内部相当于自动运行了如下代码:
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
我们可以通过如下代码来判断显示原型属性与隐式原型属性是否相等:
function Fn(){
}
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
console.log(fn.__proto__===Fn.prototype);
运行上述代码会输出:true,这说明显示原型属性与隐式原型属性确实相等。
由此我们可以总结:函数实例化对象的隐式原型属性等于其构造函数的显示原型属性。
了解过原型之后,我们来看一下原型链。
先来看一张图:

那么这个空的object对象是不是一个实例化对象呢,如果是的话,它的构造函数又是谁呢?
在回答上述问题之前我们先来看一个新的属性:constructor;
这个属性与prototype作用类似,不过不同的是:prototype是function对象指向它对应的原型对象,而constructor则是原型对象指向其对应的function对象。
举个例子:
function Fn(){
}
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
console.log(fn.__proto__.constructor);
若我们运行上述代码,则会得到如下结果:


通过这个例子我们可以知道:Fn的实例化对象fn可以通过fn.__proto__.constructor来得到自身的构造函数。
它的原理也很简单,由前面我们可以知道,fn.__proto__===Fn.prototype是成立的,所以可以通过fn.__ptoto__来得到Fn的原型对象,然后再使用constructor来得到与该原型相对应的function函数,即:Fn。
再回到前面的问题上,我们同样可以通过上述方法来获得object的构造函数。
即执行:
function Fn(){
}
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
console.log(Fn.prototype.__proto__.constructor);
其输出结果如下:

我们可以看到,object空对象的构造函数是Object。
那么问题又来了,我们知道:函数实例化对象的隐式原型属性等于其构造函数的显示原型属性。
这个object空对象的构造函数既然是Object,那么object应该也通过__ptoto__来指向一个原型对象。
即:

那么Object函数原型对象的隐式原型又指向谁呢?
我们来看一下:
function Fn(){
}
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
console.log("输出结果为:"+Fn.prototype.__proto__.__proto__);

由此可以知道:Object函数原型对象的隐式原型不再指向其他对象,即:

当我们运行如下代码时:
function Fn(){
}
var fn=new Fn(); //fn内部:this.__ptoto__=Fn.prototype
Object.prototype.name='mmzkyl';
console.log("输出结果为:"+fn.name);
会得到如下输出:

我们可以很明显看到,上述代码并没有在Fn内部定义任何东西,但是fn.name确实又输出了:mmzkyl。
这里来解释一下,当查找对象内部属性的属性/方法时,JavaScript引擎会自动沿着如下图所示来进行查找:

JavaScript会先在自身查找目标属性/方法,若是没有查找到则会沿着其隐式原型属性渠道原型对象中寻找,若是找到了则返回该值,若是还没有找到,则继续沿着隐式原型属性寻找,若是一直找到了Object函数原型对象还是没有找到,则会返回undefined。
这个寻找的过程类似与一条链,而这也称为原型链。
javaScript(原型链)的更多相关文章
- JavaScript学习总结(十七)——Javascript原型链的原理
一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中, ...
- javascript原型链中 this 的指向
为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = { d: 40 }; var a = { x: 10, calculate: function (z) ...
- 明白JavaScript原型链和JavaScrip继承
原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...
- Javascript 原型链资料收集
Javascript 原型链资料收集 先收集,后理解. 理解JavaScript的原型链和继承 https://blog.oyanglul.us/javascript/understand-proto ...
- 资料--JavaScript原型链
JavaScript原型链 原文出处:https://www.cnblogs.com/chengzp/p/prototype.html 目录 创建对象有几种方法 原型.构造函数.实例.原型链 inst ...
- JavaScript原型链:prototype与__proto__
title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...
- JavaScript原型链及其污染
JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...
- 图解Javascript原型链
本文尝试阐述Js中原型(prototype).原型链(prototype chain)等概念及其作用机制.上一篇文章(图解Javascript上下文与作用域)介绍了Js中变量作用域的相关概念,实际上关 ...
- 画一画javascript原型链
在javascript中,几种数据类型String,Number,Boolean,Object,Function都是函数,可称之为函数对象. 可以说拥有prototype属性的都是函数. 所有对象都拥 ...
- JavaScript原型链和instanceof运算符的暧昧关系
时间回到两个月前,简单地理了理原型链.prototype以及__proto__之间的乱七八糟的关系,同时也简单了解了下typeof和instanceof两个运算符,但是,anyway,试试以下两题: ...
随机推荐
- Golang Map实现(四) map 的赋值和扩容
title: Golang Map 实现 (四) date: 2020-04-28 18:20:30 tags: golang map 操作,是map 实现中较复杂的逻辑.因为当赋值时,为了减少has ...
- Scala教程之:scala的参数
文章目录 默认参数值 命名参数 scala的参数有两大特点: 默认参数值 命名参数 默认参数值 在Scala中,可以给参数提供默认值,这样在调用的时候可以忽略这些具有默认值的参数. def log(m ...
- Linux系统管理第一二三四章 系统管理 目录和文件管理 安装及管理程序 账号管理
命令 功能 序号 第一章 cd 切换目录 1 stat 查看文件状态信息 2 cp 复制 -f -i -p -r 3 du 统计磁盘的大小 4 find 精细查找文件和目录 5 help 帮助 ...
- Gym 101194F Mr. Panda and Fantastic Beasts
#include<bits/stdc++.h> using namespace std; #define ms(arr,a) memset(arr,a,sizeof arr) #defin ...
- mac OS Apache Tomcat 启动/停止服务
进入Tomcat下的bin目录 启动Tomcat命令 ./startup.sh Tomcat 默认端口 8080 停止Tomcat服务命令 ./shutdown.sh 执行tomcat ./shutd ...
- 《高性能Linux服务器构建实战》——第1章轻量级HTTP服务器Nginx
第1章 轻量级HTTP服务器Nginx本章主要介绍Nginx的配置管理和使用.作为一个轻量级的HTTP服务器,Nginx与Apache相比有以下优势:在性能上,它占用很少的系统资源,能支持更多的并发连 ...
- 数学--数论--随机算法--Pollard Rho 大数分解算法 (带输出版本)
RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试. 操作流程 首先,我们先用MillerRabinMille ...
- HTTP请求头中的X-Forwarded-For介绍
概述 我们在做nginx方向代理的时候,为了记录整个代理过程,我们往往会在配置文件中加上如下配置: location ^~ /app/download/ { ... proxy_set_header ...
- golang server示例
一个简单的web服务器 package main import ( "fmt" "log" "net/http" ) func main() ...
- CTF-Reverse-[GXYCTF2019]luck_guy
CTF-Reverse-[GXYCTF2019]luck_guy 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!本文仅用于学习与 ...