prototype 与 __proto__
原文: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__的更多相关文章
- js中的prototype和__proto__
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + thi ...
- JS的prototype和__proto__ Constructor
一.prototype和__proto__的概念 prototype是 注意是 只有函数的一个属性才有的(每个函数都有一个prototype属性),这个属性是一个指针,指向一个普通对象并且不是原型对象 ...
- prototype和__proto__
一.prototype和__proto__的概念 prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象.它是显示修改对象的原型的属性. __p ...
- Js中Prototype、__proto__、Constructor、Object、Function关系介绍
一. Prototype.__proto__与Object.Function关系介绍 Function.Object:都是Js自带的函数对象.prototype,每一个函数对象都有一个显式的proto ...
- 面向对象的程序设计(二)理解各种方法和属性typeof、instanceof、constructor、prototype、__proto__、isPrototypeOf、hasOwnProperty
//理解各种方法和属性typeof.instanceof.constructor.prototype.__proto__.isPrototypeOf.hasOwnProperty. //1.typeo ...
- 【原创】javascript——prototype与__proto__
一定要注意这个概念:javascript世界里,万物皆对象, function是对象,prototyp也是对象. 新建构造函数,并实例 var Person = function(){} var ...
- 在 JavaScript 中 prototype 和 __proto__ 有什么区别
本文主要讲三个 问题 prototype 和 proto function 和 object new 到底发生了什么 prototype 和 proto 首先我们说下在 JS 中,常常让我们感到困惑的 ...
- 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)
首先,js的数据结构有 原始类型(5种):Boolean.Number.String.Null.Underfined, 然后是引用类型:Array.Date.Error.RegExp.Function ...
- 04面向对象编程-01-创建对象 和 原型理解(prototype、__proto__)
1.JS中对象的"不同":原型概念 从Java中我们可以很好地去理解 "类" 和 "实例" 两个概念,可是在JavaScript中,这个概念 ...
- 【前端】JavaScript中prototype和__proto__的区别
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/prototype.html 经常有小伙伴问我关于prototype和__proto__的问题,觉得有必要写一篇博客 ...
随机推荐
- redis的数据持久化存储
Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化.Redis支持两种持久化方式: 一.snapshotting(快照)方式快照是默认的持久化方式. ...
- Linux下chkconfig命令详解--(启动或停止)和查询系统服务的运行级信息
chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...
- bzoj3748 Kwadraty
Claris 当然是要用来%的 但是,,其他dalao,,比如JL的红太阳commonc.题解能不能稍微加几句话,蒟蒻看不懂啊. 在这里解释一下,Claris的题解.(因为我弱,想了半天才明白,所以觉 ...
- 【HEOI 2018】制胡窜
转载请注明出处:http://www.cnblogs.com/TSHugh/p/8779709.html YJQ的题解把思路介绍得很明白,只不过有些细节说得还是太笼统了(不过正经的题解就应该这个样子吧 ...
- Cochran’s Q Test
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- 生存分析/Weibull Distribution韦布尔分布
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- Java运行原理研究(未完待续)
java的介绍和定性 java的优缺点分析 jdk的组成结构 jvm的工作原理 java的跨平台原理 java的编译和运行过程
- 2017北京国庆刷题Day3 morning
期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...
- TCP和UDP相关概念
位于传输层的协议,都是基于IP协议的. TCP是面向连接的.可靠的传输,UDP是无连接的.不可靠的传输.要进行TCp传输时候,需要进行三次握手,建立连接,然后才能发送数据,而且在发送过程中,有数据的确 ...
- E.Text Editor (Gym 101466E + 二分 + kmp)
题目链接:http://codeforces.com/gym/101466/problem/E 题目: 题意: 给你s串和t串,一个数k,求t的最长前缀串在s串中出现次数不少于k. 思路: 一眼二分+ ...