蓝色 = 函数,
绿色 = 函数作为对象时的属性,
粉色 = 构造函数的实例,
橙色 = Object构造函数的实例,也就是我们常用的真正意义上的对象(比如 var a = {}; var b = new Object() 中的 a 和 b )
每个函数默认都具有两个属性,name(函数名) 和 length(参数个数)
比如
jsfunction Person() {}; console.log(Person.name) // 'Person';
也可以直接定义属性和方法,比如
jsPerson.xx = 100;
__proto__
属性,用来指向构造出这个对象的构造函数的 prototype 。比如
jsfunction A(){}; A.prototype = {name:'a'}; var a = new A(); a.__proto__ === A.prototype // true
这样设计有什么用?
比如a对象本身是没有name属性的,但是当你访问a.name时却会得到'a',原因就是访问对象属性时,如果当前对象没有这个属性,会访问a.__proto__
.name,如果有就返回这个值,如果没有,则继续访问a.__proto__
.__proto__
.name的有没有这个属性,一直找到__proto__
为null时,返回一个undefined,结束。
那么它就同时拥有了prototype 和 __proto__
两个属性!普通对象只有__proto__
属性,可以认为prototype 是原型,__proto__
是原型链。
我个人认为,是的。
理由就是,如果我是作者,我会在在JS解释器初始化时做这样的事:
先用Function构造Function自己,
然后用Function构造一个Object,也就是 Object = new Function(), 此时Object就是一个构造函数了
再执行 Object.prototype = null;
然后执行 o = new Object, 然后给o挂在例如 asgin、keys等静态方法;
此时的 o.__proto__
为 null, 因为new出来的对象的 __proto__
指向构造函数的原型prototype。
最后执行Object.prototype = o,
这也就是为什么原型链顶端指向了null。这都是我的猜测。
再者说,Object.prototype.__proto__
如果非要有指向,那就只能指向自己,因为一个对象的 __proto__ 要等于这个对象的构造函数的prototype
,那么 Object.prototype 这个对象明显也是Object这个构造函数构造的,所以 Object.prototype.__proto__
按理说应该等于Object.prototype
但是如果这样,原型链按照__proto__
一层层查找属性到达底层就会出现死循环,这肯定不行,所以Object.prototype.__proto__
只能指向null来杜绝这种问题。
__proto__
指向了 Function.prototype ?首先,Function.prototype 指向了一个对象,严格来说,是指向了一个函数,虽然prototype指向一个函数是特殊了一点,但是这个没啥问题,因为毕竟函数也是对象。
其次,要理解 Function 构造了它自己这句话:
Function 构造出了 Function,那么 Function.__proto__
就等于 Function.prototype,因为一个对象的 __proto__ 要等于这个对象的构造函数的prototype
,所以,Function.__proto__
指向了 Function.prototype 也是合情合理的。
__proto__
指向了 Function.prototype? 不是应该指向Object.prototype 吗?作者强行修改了这个属性!!