原文:http://rockyuse.iteye.com/blog/1426510

说到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__!

prototype 与 __proto__的更多相关文章

  1. js中的prototype和__proto__

    var Person = function(name){ this.name = name; this.say = function(){ return "I am " + thi ...

  2. JS的prototype和__proto__ Constructor

    一.prototype和__proto__的概念 prototype是 注意是 只有函数的一个属性才有的(每个函数都有一个prototype属性),这个属性是一个指针,指向一个普通对象并且不是原型对象 ...

  3. prototype和__proto__

    一.prototype和__proto__的概念 prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象.它是显示修改对象的原型的属性. __p ...

  4. Js中Prototype、__proto__、Constructor、Object、Function关系介绍

    一. Prototype.__proto__与Object.Function关系介绍 Function.Object:都是Js自带的函数对象.prototype,每一个函数对象都有一个显式的proto ...

  5. 面向对象的程序设计(二)理解各种方法和属性typeof、instanceof、constructor、prototype、__proto__、isPrototypeOf、hasOwnProperty

    //理解各种方法和属性typeof.instanceof.constructor.prototype.__proto__.isPrototypeOf.hasOwnProperty. //1.typeo ...

  6. 【原创】javascript——prototype与__proto__

    一定要注意这个概念:javascript世界里,万物皆对象, function是对象,prototyp也是对象.   新建构造函数,并实例 var Person = function(){} var ...

  7. 在 JavaScript 中 prototype 和 __proto__ 有什么区别

    本文主要讲三个 问题 prototype 和 proto function 和 object new 到底发生了什么 prototype 和 proto 首先我们说下在 JS 中,常常让我们感到困惑的 ...

  8. 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)

    首先,js的数据结构有 原始类型(5种):Boolean.Number.String.Null.Underfined, 然后是引用类型:Array.Date.Error.RegExp.Function ...

  9. 04面向对象编程-01-创建对象 和 原型理解(prototype、__proto__)

    1.JS中对象的"不同":原型概念 从Java中我们可以很好地去理解 "类" 和 "实例" 两个概念,可是在JavaScript中,这个概念 ...

  10. 【前端】JavaScript中prototype和__proto__的区别

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/prototype.html 经常有小伙伴问我关于prototype和__proto__的问题,觉得有必要写一篇博客 ...

随机推荐

  1. [POJ3613] Cow Relays

    link 题目大意 给你一个含有边权的无向图,问从$S$到$T$经过$N$条边的最小花费. 试题分析 我们可以很容易推导$dp$方程,$dp(k,i,j)$表示经过$k$条边从$i$到$j$的最小花费 ...

  2. 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  3. 前端PHP入门-015-递归函数-飘过

    提要: 如果感觉吃力,web前端的各位同学,可以弃之. 递归函数,递归只是一个名字,而递归函数的规定: 函数体内调用函数自己 . 我们来计算 10!=10*9*8*7*6*5*4*3*2*1 web前 ...

  4. Tensorboard教程:显示计算图中节点信息

    Tensorboard显示计算图节点信息 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 强烈推荐Tensorflow实战Google深度学习框架 实验平台: Tensorflow1 ...

  5. Mybatis多参数及实体对象传递

    在使用Mybatis的时候,经常会有各种各样的参数传递,不同类型,不同个数的参数. 先上个例子:     public List<LifetouchRelease> findOfficeL ...

  6. bzoj 3884 欧拉定理

    求$$2^{2^{2^{2^{…}}}} mod n$$的值,其中n有1e7. 老实说这题挺有趣的,关键是怎么化掉指数,由于是取模意义下的无限个指数,所以使用欧拉定理一定是可以把指数变为不大于$\va ...

  7. Linux高级编程--04.GDB调试程序(入门概述)

    GDB概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试 ...

  8. ubuntu11下安装文件

    1.ubuntu11下安装.run文件 首先右键单击这个文件,在properties-permissions那里选择允许以程序执行(打钩Allow executing file as program) ...

  9. 更改gradle的java的class文件输出目录的结构

    group 'com.thinkvenus.common'version '1.0-SNAPSHOT' apply plugin: 'java' sourceCompatibility = 1.8 r ...

  10. 面试整理(1):原生ajax

    接到电话面试,有一些送分题答的不好,在这里整理一下 问题:原生ajax的工作流程是怎么样的? 老用封装好的工具,原生的ajax其实并不熟悉,今天复习一下.主要参考http://www.w3school ...