理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程。
我们先看看这样一段代码:
1
|
<script type= "text/javascript" >
|
2
|
var Person = function () { };
|
3
|
var p = new Person();
|
4
|
</script>
|
很简单的一段代码,我们来看看这个new究竟做了什么?我们可以把new的过程拆分成以下三步:
<1> var p={}; 也就是说,初始化一个对象p。
<2> p.__proto__=Person.prototype;
<3> Person.call(p);也就是说构造p,也可以称之为初始化p。
关键在于第二步,我们来证明一下:
1
|
<script type= "text/javascript" >
|
2
|
var Person = function () { };
|
3
|
var p = new Person();
|
4
|
alert(p.__proto__ === Person.prototype);
|
5
|
</script>
|
这段代码会返回true。说明我们步骤2的正确。
那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。
按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。
好,概念说清了,让我们看一下下面这些代码:
1
|
<script type= "text/javascript" >
|
2
|
var Person = function () { };
|
3
|
Person.prototype.Say = function () {
|
4
|
alert( "Person say" );
|
5
|
}
|
6
|
var p = new Person();
|
7
|
p.Say();
|
8
|
</script>
|
这段代码很简单,相信每个人都这样写过,那就让我们看下为什么p可以访问Person的Say。
首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性, 于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了 Person.prototype.Say=function(){}; 于是,就找到了这个方法。
好,接下来,让我们看个更复杂的。
01
|
<script type= "text/javascript" >
|
02
|
var Person = function () { };
|
03
|
Person.prototype.Say = function () {
|
04
|
alert( "Person say" );
|
05
|
}
|
06
|
Person.prototype.Salary = 50000;
|
07
|
var Programmer = function () { };
|
08
|
Programmer.prototype = new Person();
|
09
|
Programmer.prototype.WriteCode = function () {
|
10
|
alert( "programmer writes code" );
|
11
|
};
|
12
|
Programmer.prototype.Salary = 500;
|
13
|
var p = new Programmer();
|
14
|
p.Say();
|
15
|
p.WriteCode();
|
16
|
alert(p.Salary);
|
17
|
</script>
|
我们来做这样的推导:
var p=new Programmer()可以得出p.__proto__=Programmer.prototype;
而在上面我们指定了Programmer.prototype=new Person();我们来这样拆分,var p1=new Person();Programmer.prototype=p1;那么:
p1.__proto__=Person.prototype;
Programmer.prototype.__proto__=Person.prototype;
由根据上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。
好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是 Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是 Person.prototype中去找,于是就找到了alert(“Person say”)的方法。
其余的也都是同样的道理。
这也就是原型链的实现原理。
最后,其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__!
转载于:https://www.cnblogs.com/chengjun/p/5237288.html
理解js中的原型链,prototype与__proto__的关系相关推荐
- js原型和原型链_理解JS中的原型和原型链
导读:JavaScript中(JS)的原型和原型链是web前端开发面试中经常被问到的问题:同时,如果我们能很好的理解JS中的原型和原型链,对于控制台输出的很多信息我们也能更好的理解,而原型链也是实现继 ...
- 一文读懂原型链 prototype和__proto__详解
目录 1.原型对象 prototype 2.prototype 和 __proto__ 3.原型链 4.补充 5.原型链总结 1.原型对象 prototype 我们首先总结一下原型对象的作用: 原型对 ...
- JS中的原型链(超清晰理解)
什么是原型链 原型链,所有的原型构成了一个链条,这个链条我们称之为原型链(prototype chain). 原型链的案例 如果我们执行下面这段代码,因为没有定义address这个属性,程序结果理所当 ...
- 如何更加简单的理解JS中的原型原型链概念
前面写了很多关于前端经验之谈,今天就来点干货吧.这篇文章将会介绍原型这个概念 原型是整个Javascript中比较重要的概念,如果面向对象想要学好,那么这个东西你必须要了解,不然后面的原型链,继承,多 ...
- 彻底理解js中的原型对象和prototype属性
prototype(函数的原型属性) prototype 是一个指向该实例所使用的原型对象的[指针] prototype 是几乎所有的函数(除了某些内建函数)的属性 prototype 不是一个实例的 ...
- JS原型理解——JS中的原型对象
JavaScript中的原型对象 下一篇:JS原型理解--JS继承的实现方式 原型 原型是JavaScript中继承的基础,JavaScript的继承就是基于原型的继承. 一 理解原型 1.1 函数的 ...
- 【原型链】JS中的原型链到底是什么
1.构造函数 JS中的构造函数和普通函数没有本质区别,要用调用方式的不同来区分. 在调用构造函数时要用new Func()的方法来调用,此时函数会默认返回this 为了与普通函数区分,构造函数的函数名 ...
- 原型链prototype和__proto__
所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法. 显示原型和隐式原型:构造函数的显示原型用来存放函数对象,而实例对象的隐式原型等同于构函数的显示原型.所有 ...
- js原型链prototype与__proto__以及new表达式
对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model 转载 ...
最新文章
- 想象中的论文答辩和真实的论文答辩!哈哈哈哈哈哈……
- Android平台使用PocketSphinx做离线语音识别,小范围语音99%识别率
- sple表达式_学习Spring表达式语言(SpEL)
- 33 | 关于 Linux 网络,你必须知道这些(上)
- 左神算法:将搜索二叉树转换成双向链表(Java版)
- 这些器件是电子垃圾?是艺术作品!!!
- mysql添加 分隔_分割字符串并插入表---mysql
- 这么多人,AI怎么知道你说的是哪个? | 李飞飞团队CVPR论文+代码
- 携程、快手、平安银行、哈啰出行是怎么落地数据治理和DataOps的?丨DAMS峰会...
- php 微信表情字符,微信公众平台开发--表情符号
- AI 人工智能学习之需要具备的基础知识
- JS动态生成表格案例
- word中-文字尾部空格自动添加下划线的步骤
- 读书笔记 大前研一《专业主义》
- vue邮箱验证正则表达式错误:Unterminated regular expression
- Scrape Center爬虫平台之spa8案例
- 【STM32】标准库-SDIO-SDHC
- web接入大华摄像头实时视频
- MATLAB :xlim 、 ylim 、zlim简介
- 美国国土安全部和MSF相继发布了Citrix漏洞的测试利用工具
热门文章
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(1)-实现一个简单的bootloader
- [转]用g++编译动态链接库
- nodejs开发 过程中express路由与中间件的理解 - pyj063 - 博客园
- ConfigurableListableBeanFactory
- github中的watch、star、fork的作用
- 数组黑科技(偏性能方面)未完待更新...
- javascript --- 实现Ajax的代码
- 使用mockjs模拟数据
- 【翻译自mos中文文章】重建控制文件的方法
- BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离