JS一切皆对象理解
对象都是通过函数创建的
function Fn() { this.name = '王福朋'; this.year = 1988; } var fn1 = new Fn();
fn1是个对象,它是由函数Fn创建的,但是我要说都大家可能会反驳,不信你往下看
var obj = { a: 10, b: 20 }; var arr = [5, 'x', true];
但是不好意思,这个——真的——是一种——“快捷方式”,在编程语言中,一般叫做“语法糖”。
做“语法糖”做的最好的可谓是微软大哥,它把他们家C#那小子弄的不男不女从的,本想图个人见人爱,谁承想还得到处跟人解释——其实它是个男孩!
话归正传——其实以上代码的本质是:
//var obj = { a: 10, b: 20 }; //var arr = [5, 'x', true]; var obj = new Object(); obj.a = 10; obj.b = 20; var arr = new Array(); arr[0] = 5; arr[1] = 'x'; arr[2] = true;
而其中的 Object 和 Array 都是函数:
console.log(typeof (Object)); // function console.log(typeof (Array)); // function
可以很负责任的说——对象都是通过函数来创建的。
可以很负责任的说——对象都是通过函数来创建的。
每个对象都有一个__proto__属性,指向创建该对象的函数的prototype。
var obj = { }
console.log(obj._proto_)
obj这个对象本质上是被Object函数创建的,因此obj.__proto__=== Object.prototype
如图所示
即,每个对象都有一个__proto__属性,指向创建该对象的函数的prototype。
那么上图中的“Object prototype”也是一个对象,它的__proto__指向哪里?
好问题!
在说明“Object prototype”之前,先说一下自定义函数的prototype。自定义函数的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以它的__proto__指向的就是Object.prototype。
但是Object.prototype确实一个特例——它的__proto__指向的是null,切记切记!
还有——函数也是一种对象,函数也有__proto__吗?
又一个好问题!——当然有。
函数也不是从石头缝里蹦出来的,函数也是被创建出来的。谁创建了函数呢?——Function——注意这个大写的“F”。
且看如下代码。
以上代码中,第一种方式是比较传统的函数创建方式,第二种是用new Functoin创建。
首先根本不推荐用第二种方式。
这里只是向大家演示,函数是被Function创建的。
好了,根据上面说的一句话——对象的__proto__指向的是创建它的函数的prototype,就会出现:Object.__proto__ === Function.prototype。用一个图来表示。
上图中,很明显的标出了:自定义函数Foo.__proto__指向Function.prototype,Object.__proto__指向Function.prototype,唉,怎么还有一个……Function.__proto__指向Function.prototype?这不成了循环引用了?
对!是一个环形结构。
其实稍微想一下就明白了。Function也是一个函数,函数是一种对象,也有__proto__属性。既然是函数,那么它一定是被Function创建。所以——Function是被自身创建的。所以它的__proto__指向了自身的Prototype。