您的位置:首页 > 其它

关于__proto__和prototype

2014-11-20 16:23 330 查看


首先放一个在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. 基础是上面提到的那两个基本规则!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: