我们先看看这样一段代码:

  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(){}; 于是,就找到了这个方法。

好,接下来,让我们看个更复杂的。

  1. <script>
  2. 'use strict';
  3. var Person = function () {};
  4. Person.prototype.Say = function () {
  5. alert("Person say");
  6. }
  7.  
  8. Person.prototype.Salary = 50000;
  9. var Programmer = function () {
  10. };
  11. Programmer.prototype = new Person();
  12. Programmer.prototype.WriteCode = function () {
  13.  
  14. alert("programmer writes code");
  15.  
  16. };
  17.  
  18. Programmer.prototype.Salary = 500;
  19.  
  20. var p = new Programmer();
  21. p.Say(); /*Person say*/
  22. p.WriteCode(); /*programmer writes code*/
  23. alert(p.Salary); /**/
  24.  
  25. /*
  26. * p.__proto__ = Programmer.prototype;
  27. * Programmer.prototype = Person.prototype;
  28. * p.__proto__.__proto__ = Person.prototype;
  29. * */
  30. </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__!

javascript中 __proto__与prorotype的理解的更多相关文章

  1. JavaScript中call、apply个人理解

    JavaScript中call.apply个人理解 一句话即通俗的说:call.apply 是为了改变this的状态而存在的 }; } function personInfo(name,age){ t ...

  2. JavaScript中__proto__与prototype的关系

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...

  3. JavaScript中__proto__与prototype的关系(转)

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...

  4. javascript 中的new操作符的理解

    new 操作符 在有上面的基础概念的介绍之后,在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在Javascript中,我们将这类方式成为Pseudoclassic ...

  5. 对JavaScript中变量类型的重新理解

    <JavaScript启示录>这本书中提出:JavaScript中,对象为“王”(JavaScript里的几乎所有东西都是对象或者用起来像对象). 飞燕草对JavaScript最深刻的理解 ...

  6. javascript中闭包与作用域的理解

    很多js的框架与插件编写都用到了闭包,所以,阅读和掌握闭包很有必要.最近学习vue框架时,经常会猜想很多功能的native js实现,很多都应用到了闭包,闭包除了目前已知的一些特性,如:可以保持局部变 ...

  7. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

  8. JavaScript中一些怪异用法的理解

    引言 JavaScript这门语言有些场合的用法还是比较怪异的.这篇文章会尽量将这门语言特有的一些比较特殊的用法收集在一起.就当是平时开发时需要注意的地方吧. 特殊用法收集 1.!!用法 在JavaS ...

  9. JavaScript中的this对象指向理解

    在JavaScript中,this不是固定不变的,它的指向取决于上下文环境,一般的,认为this指向使用它时所在的对象.主要有以下几类指向: 在方法中,this 表示该方法所属的对象. 如果单独使用, ...

随机推荐

  1. C#网络程序设计(2)Socket基础编程

        本节介绍如何使用基础Socket实现TCP通信.     (1)Socket详细介绍: Socket的英文原义是"孔"或"插座".通常称作"套 ...

  2. # Android动画笔记

    标签: Android开发艺术探索笔记 View动画 帧动画 属性动画 View动画 View动画的作用对象时View,有4种动画效果,分别是平移动画.缩放动画.旋转动画.和透明度动画. 此类动画通常 ...

  3. [ext4]01 磁盘布局 - block分析

    ext4文件系统最基本的分配单元是"block"(块). block是由一组连续的sectors来组成,其大小介于1k~4K之间,当然不可能是任意值,只能是2的整数次幂个secto ...

  4. Web常见约定规范(精选)

    常见的约定规范 (一)HTML约定规范 1,html属性顺序:id class name data-xxx (src for type href)(title alt)(aria-xxx role) ...

  5. 每天一道Java题[1]

    问题:char[]与String相比,有什么优胜的地方? 回答: 针对安全保密高的信息,char[]比String做得更好.因为String是不可变得,即使你修改原先的变量,实际上也是在内存中新建一个 ...

  6. 支付宝app支付服务器签名代码(C#)

    1,引入支付宝的sdk(AopSdk) 支付宝接口文档网站可下载,注意下载C#版本: 2,代码写的比较简单 public static string RSASign(string OrderNo,de ...

  7. Java学习笔记——浅谈数据结构与Java集合框架(第二篇、Queue、Set)

    江南好,何处异京华. 香散翠帘多在水,绿残红叶胜于花.无事避风沙. --<纳兰词> 诗词再好,大图不能忘 上大图: 先说说栈和队列: 栈就好比手枪的弹匣,你往里面压入子弹,最先压入的子弹就 ...

  8. VMTools安装

    先启动CentOS并成功登陆如下图,发现底部提示,准备安装 2.选择虚拟机菜单栏--安装VMware tools 3.光驱目录中拷贝VMwareTools-10.0.5-3228253.tar.gz到 ...

  9. App架构经验总结(转载)

    原文地址:http://www.iteye.com/news/31472 架构因人而异,不同的架构师大多会有不同的看法:架构也因项目而异,不同的项目需求不同,相应的架构也会不同.然而,有些东西还是通用 ...

  10. 桥梁模式(Bridge Pattern)

    桥梁模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥梁模式的用意是“将抽象化(Abstraction)与实现化(Implementation) ...