四. __proto__
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__
的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1 有一个 __proto__
属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:
person1.__proto__ == Person.prototype
请看下图:
《JavaScript 高级程序设计》的图 6-1
根据上面这个连接图,我们能得到:
Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;
不过,要明确的真正重要的一点就是,这个连接存在于实例(person1
)与构造函数(Person
)的原型对象(Person.prototype
)之间,而不是存在于实例(person1
)与构造函数(Person
)之间。
注意:因为绝大部分浏览器都支持__proto__属性,所以它才被加入了 ES6 里(ES5 部分浏览器也支持,但还不是标准)。
五. 构造器
熟悉 Javascript 的童鞋都知道,我们可以这样创建一个对象:
var obj = {}
它等同于下面这样:
var obj = new Object()
obj 是构造函数(Object)的一个实例。所以:
obj.constructor === Object
obj.__proto__ === Object.prototype
新对象 obj 是使用 new 操作符后跟一个构造函数来创建的。构造函数(Object)本身就是一个函数(就是上面说的函数对象),它和上面的构造函数 Person 差不多。只不过该函数是出于创建新对象的目的而定义的。所以不要被 Object 吓倒。
同理,可以创建对象的构造器不仅仅有 Object,也可以是 Array,Date,Function等。
所以我们也可以构造函数来创建 Array、 Date、Function
var b = new Array();
b.constructor === Array;
b.__proto__ === Array.prototype;
var c = new Date();
c.constructor === Date;
c.__proto__ === Date.prototype;
var d = new Function();
d.constructor === Function;
d.__proto__ === Function.prototype;
这些构造器都是函数对象:
函数对象六. 原型链
小测试来检验一下你理解的怎么样:
-
person1.__proto__
是什么? -
Person.__proto__
是什么? -
Person.prototype.__proto__
是什么? -
Object.__proto__
是什么? -
Object.prototype__proto__
是什么?
答案:
第一题:
因为 person1.__proto__ === person1 的构造函数.prototype
因为 person1的构造函数 === Person
所以 person1.__proto__ === Person.prototype
第二题:
因为 Person.__proto__ === Person的构造函数.prototype
因为 Person的构造函数 === Function
所以 Person.__proto__ === Function.prototype
第三题:
Person.prototype
是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。
因为一个普通对象的构造函数 === Object
所以 Person.prototype.__proto__ === Object.prototype
第四题,参照第二题,因为 Person 和 Object 一样都是构造函数
第五题:
Object.prototype
对象也有proto属性,但它比较特殊,为 null 。因为 null 处于原型链的顶端,这个只能记住。
Object.prototype.__proto__ === null
好了,如果以上你都能明白,那就可以继续深入学习第三篇教程了:
第三篇,点击进入
网友评论
因为 Object.prototype 是个对象
并且对象的__proto__又指向其构造函数的原型(Object.prototype)
所以会有如下奇怪的等式: Object.prototype.__proto__ === Object.prototype
估计这种逻辑上的死循环很难解释了吧(我瞎猜的)
原型对象(Person.prototype)是 构造函数(Person)的一个实例。
var A = new Person();
Person.prototype = A;
但是这一讲开头就“person1.__proto__ == Person.prototype”
实际上A和person1都是Person的实例吧,那么岂不是person1.__proto__ = person1了。
原型链的形成是真正是靠__proto__ 而非prototype
得出这个连接即__proto__
Function.prototype,就是他自己,自己指向自己,没有意义。
JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向Object.prototype。Object.prototype.__proto__ === null,保证原型链能够正常结束。
typeof 构造函数名.prototype.__ptoto__ 都是'object' ?
但是 typeof Object 是 'function'
Person.prototype.constructor === Person; // true
那 Person.prototype.__proto__不就应该是 Person.prototype的构造函数的prototype,也就是Person.prototype
为什么会是Obejct.prototype呢
我觉得好像哪不对,又找不到
文中写到
var obj = {}
它等同于下面这样:
var obj = new Object()
那么这个obj应该是一个普通对象(非函数对象)对么?所以说这个obj是不是也就没有prototype属性了?谢谢!
1、原型对象是普通对象
2、普通对象的构造 === Object
3、对象的_proto_属性指向其构造方法的原型对象
conclusion:Object.prototype._proto_ === Object.prototype
答案却是: Object.prototype._proto_ === null
你记住这句:每个对象都有 __proto__ 属性,但只有函数对象才有 prototype
在教程一里写的有
这一句没太理解,按照上文函数对象的prototype指向这个函数的一个实例,例如person1.prototype===new Person()也就是说Person.prototype是一个Person的实例,Person的实例的构造函数应该是Person啊?为啥会是Object呢?求解,谢谢哈。
http://www.0313.name/2017/01/23/prototype2.html
上面漏写一个点
这句话是否有错误:Person.prototype[的构造函数] === Person
因为 Person.__proto__ === person1[的构造函数].prototype
这里写错了吧
准备好好再整理下同步到 GitHub 上,以后如果有更新也会同步到上去
https://github.com/zaxlct/javascript-tutorial 嘿嘿。