[转]理解js中的原型链,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__!
[转]理解js中的原型链,prototype与__proto__的关系的更多相关文章
- 理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...
- 【转】理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...
- 理解js中的原型链
对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 关于原型 在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承 ...
- JavaScript原型链:prototype与__proto__
title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...
- 关于js中的原型链的理解
我们知道无论什么时候只要创建了一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象,默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包 ...
- 深入理解JS对象和原型链
函数在整个js中是最复杂也是最重要的知识 一个函数中存在多面性: 1.它本身就是一个普通的函数,执行的时候形成的私有作用域(闭包),形参赋值,预解释,代码执行,执行完 成后栈内存销毁/不销毁. 2.& ...
- 理解js中的原型,原型对象,原型链
目录 理解原型 理解原型对象 实例属性与原型属性的关系 更简单的原型语法 原型的动态性 原型链 理解原型 我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象, ...
- JS中注意原型链的“指向”
昨天压缩Js文件时发现了项目中的一个prototype的问题代码如下所示: 1. <script> var XXX = function(){ }; var x1 = new XXX(); ...
- JS中的原型链和原型的认识
这篇文章主要是学习一下JavaScript中的难点------原型和原型链 自定义一个对象 我们学习一门编程语言,必然要使用它完成一些特定的功能,而面向对象的语言因为符合人类的认知规律,在这方面做得很 ...
随机推荐
- libsvm使用简介
libsvm是support vector machine的一种开源实现,采用了smo算法.源代码编写有独到之处,值得一睹. 常用结构 svm_node结构 定义了构成输入特征向量的元素,index为 ...
- 四步走查智能硬件异常Case
此文已由作者于真真授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 相比于软件,智能硬件产品由于涉及硬件和软件两个端的状态,其异常case要更加错综复杂.由于硬件产品的迭代更新 ...
- JavaScript 测试和捕捉(try与catch)
JavaScript 测试和捕捉 try 语句允许我们定义在执行时进行错误测试的代码块. catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块. JavaScript 语句 try ...
- JavaEE常用开发工具分享
链接:https://pan.baidu.com/s/1Jxd2Y45LhWAUHc8-dM_ukw 提取码:h50f
- B - EXCEL排序(sort+结构体)
Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. Input测试输入包含若干测试用例.每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的 ...
- 解决“System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本”的问题
以server2008为例: 首先确保使用sqlplus能访问数据库. 1.管理工具->计算机管理->本地用户和组->组->administrators属性,添加,高级,立即查 ...
- Python之函数练习题
一.简述普通参数.指定参数.默认参数.动态参数的区别 普通参数:就是放入一个形参,当放入实参时,需要按照顺序给形参值. 指定参数:放入实参时是指定的,不用按照顺序给形参,都能让形参获得相应的参数. 默 ...
- 解读人:林山云,Proteomic Identification of Protein Glutathionylation in Cardiomyocytes(心肌细胞蛋白质谷胱甘肽修饰的蛋白质组鉴定)
发表时间:(2019年4月) IF:3.950 单位:韦恩州立大学化学系 物种:小鼠心肌细胞 技术:谷胱甘肽修饰蛋白组学 一. 概述: 本研究采用化学选择性蛋白组学方法,鉴定出过氧化物诱导HL-1小鼠 ...
- P3749 [六省联考2017]寿司餐厅 最小割
\(\color{#0066ff}{ 题目描述 }\) Kiana 最近喜欢到一家非常美味的寿司餐厅用餐. 每天晚上,这家餐厅都会按顺序提供 \(n\) 种寿司,第 \(i\) 种寿司有一个代号 \( ...
- 最短路【洛谷P3946】ことりのおやつ(小鸟的点心)
P3946 ことりのおやつ(小鸟的点心) 滑完雪之后,ことり突然想吃点心啦!于是她去了甜品店. 日本的冬天经常下雪.不幸的是,今天也是这样,每秒钟雪的厚度会增加q毫米. 秋叶原共有n个地点,编号从1到 ...