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

 <script type="text/javascript">
var Person = function () { };
var p = new Person();
</script>

我们来看看这个new究竟做了什么?我们可以把new的过程拆分成以下三步:

<1> var p={}; 也就是说,初始化一个对象p。

<2> p.__proto__=Person.prototype;

<3> Person.call(p);也就是说构造p,也可以称之为初始化p。

关键在于第二步,我们来证明一下:

 <script type="text/javascript">
var Person = function () { };
var p = new Person();
alert(p.__proto__ === Person.prototype);
</script>

这段代码会返回true。说明我们步骤2的正确。

那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。

按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。

好,概念说清了,让我们看一下下面这些代码:

 <script type="text/javascript">
var Person = function () { };
Person.prototype.Say = function () {
alert("Person say");
}
var p = new Person();
p.Say();
</script>

这段代码很简单,相信每个人都这样写过,那就让我们看下为什么p可以访问Person的Say。

首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性, 于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了 Person.prototype.Say=function(){}; 于是,就找到了这个方法。

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

 <script>
'use strict';
var Person = function () {};
Person.prototype.Say = function () {
alert("Person say");
} Person.prototype.Salary = 50000;
var Programmer = function () {
};
Programmer.prototype = new Person();
Programmer.prototype.WriteCode = function () { alert("programmer writes code"); }; Programmer.prototype.Salary = 500; var p = new Programmer();
p.Say(); /*Person say*/
p.WriteCode(); /*programmer writes code*/
alert(p.Salary); /**/ /*
* p.__proto__ = Programmer.prototype;
* Programmer.prototype = Person.prototype;
* p.__proto__.__proto__ = Person.prototype;
* */
</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. [Day03] 循环语句、list相关练习题

    用户输入两个数,求平均值. 让用户一直输入数字,如果输入的是'0',终止程序打印所有数字之和. 让用户一直输入数字(只输入数字),如果没输入任何值,终止程序打印所有输入数字的平均值. 求出这个list ...

  2. [codevs]1087麦森数

    题目 这个题在noiOJ上是分治专题,这个题包括了很多,求位数,高精度乘,快速幂. 那么单独把这个高精度拿出来做一个自定义函数即可 一.求位数 显而易见,既然是2进制的就是log2X,是10进制就是l ...

  3. 针对Mac的DuckHunter攻击演示

    0x00 HID 攻击 HID是Human Interface Device的缩写,也就是人机交互设备,说通俗一点,HID设备一般指的是键盘.鼠标等等这一类用于为计算机提供数据输入的设备. DuckH ...

  4. GTK简单了解记录

    GTK+http://zh.wikipedia.org/wiki/GTK%2B#.E5.9B.BE.E5.BD.A2.E6.97.A0.E5.85.B3.E4.BB.A3.E7.A0.81 GTK+最 ...

  5. MySQL修改表字段相关信息

    昨天收获颇多,首先回顾一下有关mysql的内容. 我在查询表信息时,出现了 empty set 0.00 sec 的错误,我很奇怪,仔细检查发现原来是表字段名称写错了, 于是我想修改字段名称,经过查询 ...

  6. Python:学会创建并调用函数

    这是关于Python的第4篇文章,主要介绍下如何创建并调用函数. print():是打印放入对象的函数 len():是返回对象长度的函数 input():是让用户输入对象的函数 ... 简单来说,函数 ...

  7. SQL SERVER 的前世今生--各版本功能对比

    背景 今天举办的 Data Amp 大会上,微软向开发者们强调了 数据如何影响他们的应用和服务 ,顺道还宣布了几个小新闻.这个免费的线上研讨会不仅展示了未来的机器学习远景,还发布了 SQL Serve ...

  8. 前端框架对比之vue与regular(一)

    每次一写到Regular总是忍不住先介绍一下,Regualr是网易杭州研究所的一位叫郑海波的大神写的一款前端框架,目前 这款框架推广的不深,加上其和angular过于相似的框架名,导致接受力并不大,其 ...

  9. Brief introduction to Java String Split 【简单介绍下Java String Split】

    Split is a common function in Java. It split a full string to an array based on delimeter. For examp ...

  10. React Native技术做的一个项目“微笑阅读”

    最近用React Native做了一个APP应用,有点心得: React Native确实比Hybrid应用渲染快,响应快,用户体验更好: React Native比原生简单多了,会Js就可以了,开发 ...