JavaScript: __proto__和prototype

图来源于:http://www.cnblogs.com/smoothLily/p/4745856.html
个人的理解:
1. 所有对象都有 __proto__属性,返回该对象的原型对象。例如f1由语句var f1 = new Foo()生成,那么f1.__proto__就是由构造函数Foo生成的原型对象Foo.prototype.
f1.__proto__ === Foo.prototype; //true
2. 所有函数具有prototype属性,这是一个指针,指向函数所生成对象的原型对象。Foo.prototype就是由 new Foo()函数所生成的这一类对象的原型,原型是可以被修改的:
function Foo(){};
var f1 = new Foo();
Foo.prototype.name = "emily";
f1.name; // "emily"
如上代码所示,先生成对象f1,然后修改其对象原型,给它增加了一个name属性。f1因此也有了name属性。
3. 但是函数也是一种对象,因此它也有__proto__属性,即也有其原型对象。对于函数(对象)Foo来说:
Foo.__proto__ === Function.prototype; // true
Function.prototype就是由new Function()所生成的这一类对象的原型。
函数(对象)Foo的原型正是由Function函数所生成的原型。
4. JavaScript的内置函数如Function, Object, Array, Date等,都既是构造函数,又是对象,因此他们都有prototype和__proto__属性。
不同的是prototype指向的是其本身作为构造函数作用时所生成的对象的原型对象。
而__proto__属性是返回其本身作为对象的原型对象。
Function.__proto__ === Function.prototype; //true
Array.__proto__ === Function.prototype; //true
Date.__proto__ === Function.prototype; //true
Object.__proto__ === Function.prototype; //true
Foo.__proto__ === Function.prototype; //true
5. 如上所示,所有(构造函数)对象的原型对象都是Function.prototype,这也是一个对象,在console中查看该对象,发现它返回的是一个空函数:
Function.prototype.toString(); // 返回"function () {}"
那么这个对象有没有原型对象呢,它的__proto__返回什么呢?
Function.prototype.__proto__ === Object.prototype; // true
所以
Function.__proto__.__proto__ === Object.prototype; // true Array.__proto__.__proto__ === Object.prototype; // true
Date.__proto__.__proto__ === Object.prototype; // true
Object.__proto__.__proto__ === Object.prototype; // true
Foo.__proto__.__proto__ === Object.prototype; // true
6. Object.prototype也是一个对象,因此其__proto__属性返回:
Object.prototype.__proto__; // null
因此
Function.__proto__.__proto__.__proto__; // null
Array.__proto__.__proto__.__proto__; // null
Date.__proto__.__proto__.__proto__; // null
Object.__proto__.__proto__.__proto__; // null
Foo.__proto__.__proto__.__proto__; // null
f1.__proto__.__proto__.__proto__; // null
任何对象向上回溯最终都会到null。
7. 关于原型对象的constructor属性:每个函数对象都有名为“prototype”的属性,用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用
Foo.prototype.constructor === Foo; //true
总结:理解这个概念的关键点就在于,__proto__是对象的属性,是用来向上查找其原型对象的。
而prototype是函数的属性,其作用指向该构造函数所生成对象的原型。
此外在stackoverflow上对这个问题的回答很有意思:
__proto__ is the actual object that is used in the lookup chain to resolve methods, etc.
prototype is the object that is used to build __proto__ when you create an object with new:
(new Foo).__proto__ === Foo.prototype; // 函数调用prototype属性用来构造对象原型 (new Foo).prototype === undefined; // 对象没有prototype属性
JavaScript: __proto__和prototype的更多相关文章
- JavaScript - __proto__和prototype,原形
参考 https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript 区别 构造函数中的prototype创建 ...
- JavaScript中__proto__与prototype的关系
一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...
- 15条规则解析JavaScript对象布局(__proto__、prototype、constructor)
大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...
- javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)
大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...
- 对于JavaScript对象的prototype和__proto__的理解
一.Object和Function的关系: 刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象.瞬间觉 ...
- Javascript中的__proto__、prototype、constructor
今天重温了下Javacript,给大家带来一篇Javascript博文,相信对于Javacript有一定了解的人都听过prototype原型这个概念,今天我们深度的分析下prototype与__pro ...
- JavaScript中的prototype和__proto__细致解析
最近在学js,体会了一点点它的灵活性.对于初学者的我,总是被它的灵活感到晕头转向,最近发现了一点东西想与大家分享. JavaScript中的prototype和_proto_: 我们先了解一点js中的 ...
- JavaScript:Function/Object/prototype/__proto__
console.log(Object.__proto__===Function.prototype); //true console.log(Object.prototype.__proto__); ...
- javascript中构造器(函数)的__proto__与prototype初探
背景:最近没什么需求,快要闲出屁了,所以重温了一下js的原型,结果大有收获,且偶然看到Snandy大神的<JavaScript中__proto__与prototype的关系> 这篇文章,感 ...
随机推荐
- JS整数验证
整数验证 方法1 function ValidatInteger(obj) { var reg = /^[1-9]\d*$/ if (!reg.test($(obj).val())) { $(obj) ...
- sparkSQL中udf的使用
在Spark中使用sql时一些功能需要自定义方法实现,这时候就可以使用UDF功能来实现 多参数支持 UDF不支持参数*的方式输入多个参数,例如String*,不过可以使用array来解决这个问题. 定 ...
- 【51nod1443】路径和树(堆优化dijkstra乱搞)
点此看题面 大致题意:给你一个无向联通图,要求你求出这张图中从u开始的权值和最小的最短路径树的权值之和. 什么是最短路径树? 从\(u\)开始到任意点的最短路径与在原图中相比不变. 题解 既然要求最短 ...
- 【BZOJ3940】[USACO2015 Feb] Censoring (AC自动机的小应用)
点此看题面 大致题意: 给你一个文本串和\(N\)个模式串,要你将每一个模式串从文本串中删去.(此题是[BZOJ3942][Usaco2015 Feb]Censoring的升级版) \(AC\)自动机 ...
- [solr 管理界面] - 索引数据删除
删除solr索引数据,使用XML有两种写法: 1) <delete><id>1</id></delete> <commit/> 2) < ...
- AngularJS 应用
AngularJS模块(Module)定义了AngularJS的应用. AngularJS控制器(Controller)用于控制AngularJS应用. ng-app指令定义了应用,ng-contro ...
- c++ bitset 10进制转二进制
#include <bitset> using namespace std; void main() { int a; cin>>a; cout<<bitset&l ...
- Vue 父组件传值到子组件
vue 父组件给子组件传值中 这里的AccessList就是子组件 如果 是静态传值的话直接 msg="xxx"就好 这里动态取值的话就 :msg=xxxxx ________ ...
- Java,集合按自定义规则排序
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...
- RPC框架 - thrift 客户端
-------客户端程序 ------ 下载 下载 thrift 源代码包 下载 thrift 的bin包 准备描述文件(使用源代码包的示例文件) \thrift-0.10.0\tu ...