说到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__的关系相关推荐

  1. js原型和原型链_理解JS中的原型和原型链

    导读:JavaScript中(JS)的原型和原型链是web前端开发面试中经常被问到的问题:同时,如果我们能很好的理解JS中的原型和原型链,对于控制台输出的很多信息我们也能更好的理解,而原型链也是实现继 ...

  2. 一文读懂原型链 prototype和__proto__详解

    目录 1.原型对象 prototype 2.prototype 和 __proto__ 3.原型链 4.补充 5.原型链总结 1.原型对象 prototype 我们首先总结一下原型对象的作用: 原型对 ...

  3. JS中的原型链(超清晰理解)

    什么是原型链 原型链,所有的原型构成了一个链条,这个链条我们称之为原型链(prototype chain). 原型链的案例 如果我们执行下面这段代码,因为没有定义address这个属性,程序结果理所当 ...

  4. 如何更加简单的理解JS中的原型原型链概念

    前面写了很多关于前端经验之谈,今天就来点干货吧.这篇文章将会介绍原型这个概念 原型是整个Javascript中比较重要的概念,如果面向对象想要学好,那么这个东西你必须要了解,不然后面的原型链,继承,多 ...

  5. 彻底理解js中的原型对象和prototype属性

    prototype(函数的原型属性) prototype 是一个指向该实例所使用的原型对象的[指针] prototype 是几乎所有的函数(除了某些内建函数)的属性 prototype 不是一个实例的 ...

  6. JS原型理解——JS中的原型对象

    JavaScript中的原型对象 下一篇:JS原型理解--JS继承的实现方式 原型 原型是JavaScript中继承的基础,JavaScript的继承就是基于原型的继承. 一 理解原型 1.1 函数的 ...

  7. 【原型链】JS中的原型链到底是什么

    1.构造函数 JS中的构造函数和普通函数没有本质区别,要用调用方式的不同来区分. 在调用构造函数时要用new Func()的方法来调用,此时函数会默认返回this 为了与普通函数区分,构造函数的函数名 ...

  8. 原型链prototype和__proto__

    所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法. 显示原型和隐式原型:构造函数的显示原型用来存放函数对象,而实例对象的隐式原型等同于构函数的显示原型.所有 ...

  9. js原型链prototype与__proto__以及new表达式

    对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model 转载 ...

最新文章

  1. 想象中的论文答辩和真实的论文答辩!哈哈哈哈哈哈……
  2. Android平台使用PocketSphinx做离线语音识别,小范围语音99%识别率
  3. sple表达式_学习Spring表达式语言(SpEL)
  4. 33 | 关于 Linux 网络,你必须知道这些(上)
  5. 左神算法:将搜索二叉树转换成双向链表(Java版)
  6. 这些器件是电子垃圾?是艺术作品!!!
  7. mysql添加 分隔_分割字符串并插入表---mysql
  8. 这么多人,AI怎么知道你说的是哪个? | 李飞飞团队CVPR论文+代码
  9. 携程、快手、平安银行、哈啰出行是怎么落地数据治理和DataOps的?丨DAMS峰会...
  10. php 微信表情字符,微信公众平台开发--表情符号
  11. AI 人工智能学习之需要具备的基础知识
  12. JS动态生成表格案例
  13. word中-文字尾部空格自动添加下划线的步骤
  14. 读书笔记 大前研一《专业主义》
  15. vue邮箱验证正则表达式错误:Unterminated regular expression
  16. Scrape Center爬虫平台之spa8案例
  17. 【STM32】标准库-SDIO-SDHC
  18. web接入大华摄像头实时视频
  19. MATLAB :xlim 、 ylim 、zlim简介
  20. 美国国土安全部和MSF相继发布了Citrix漏洞的测试利用工具

热门文章

  1. linux0.11学习笔记-技术铺垫-简单AB任务切换程序(1)-实现一个简单的bootloader
  2. [转]用g++编译动态链接库
  3. nodejs开发 过程中express路由与中间件的理解 - pyj063 - 博客园
  4. ConfigurableListableBeanFactory
  5. github中的watch、star、fork的作用
  6. 数组黑科技(偏性能方面)未完待更新...
  7. javascript --- 实现Ajax的代码
  8. 使用mockjs模拟数据
  9. 【翻译自mos中文文章】重建控制文件的方法
  10. BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离