关于__proto__和prototype


首先放一个在stackoverflow上的图片,该问题的地址:

http://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype

记住两条基本规则:

1. 所有的构造函数(也就是类,虽然JS中没有类的概念)和函数的__ptoto__都指向Function.prototype,它是一个空函数。

2. 所有对象的__proto__都指向它的构造函数的prototype。

下面以例子来说明规则:

Number.__proto__ === Function.prototype // true 
Boolean.__proto__ === Function.prototype // true 
String.__proto__ === Function.prototype // true 
Object.__proto__ === Function.prototype // true 
Function.__proto__ === Function.prototype // true 
Array.__proto__ === Function.prototype // true 
RegExp.__proto__ === Function.prototype // true 
Error.__proto__ === Function.prototype // true 
Date.__proto__ === Function.prototype // true 

上面都是JS内置的构造函数。另外对于普通的函数:

function f(){};

f.__proto__ === Function.prototype // true

其实在JS中构造函数和一般函数没有本质的区别,只不过构造函数一般是通过new新的对象来使用,作为类存在,而普通函数都是直接调用。

Math.__proto__ === Object.prototype // true 
JSON.__proto__ === Object.prototype // true 

Math和JSON是JS内置的对象,使用时无需通过new新的对象来使用,所以它们的构造函数也就是Object。

"abc".__proto__ === String.prototype // true

String对象的构造函数是String

var x = {a: 123};
x.__proto__ == Object.prototype // true

一般的对象的构造函数同样是Object。

function Person(){};

Person.prototype.x = 123;

var p = new Person();

p.__proto__ === Person.prototype // true

对于自定义的构造函数也是一样的,而且:

p.__proto__ === p.constructor.prototype // true

因为p.constructor就是Person。(条件是修改原型)

但是如果是重写原型:

function Person(name) { 
this.name = name 

// 重写原型 
Person.prototype = { 
getName: function() {} 

var p = new Person('jack') 
console.log(p.__proto__ === Person.prototype) // true 
console.log(p.__proto__ === p.constructor.prototype) // false

那么p.constructor就是Object了,因为p本身没有constructor那么就去寻找p.__proto__的constructor,即Person.prototype的constructor,由于上面Person.prototype是重写的新的对象,它的constructor是Object。

Function.prototype是唯一一个typeof XXX.prototype为 “function”的prototype。其它的构造器的prototype都是一个对象。


总结:

1. __proto__在编程中尽量避免使用,研究它只是用于理解原型和原型链的关系。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

2. 在查找对象的属性时,首先查找自身属性,如果没有,查找对象的__proto__中的属性,以此类推。

3. prototype可以理解为为子对象共享属性的一个接口。

4. __proto__中的属性可以直接 对象名. 取得,而prototype中的属性必须 对象名.prototype.name 取得。

5. 基础是上面提到的那两个基本规则!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值