JavaScript之Function 和 Object 的区别和联系
1、先看一个控制台的输出:
instanceof 运算符字面意思是 左边是右边的一个实例吗?
但是这两条输出让人很困惑。Function 是 Object 的实例。Object 也是 Function 的实例。
学过静态语言的人看了一下就蒙了。A是B类 的实例,B又是A的实例。是不是很扯。
实际上instanceof 运算符的意识是:左边操作数的__proto__原型链上是否包括右边操作数的prototype。
也即如果有表达式:L instance R;
则运算结果是: L.__proto__.__proto__... === R.prototype ?
运算符左边最终结果是 instanceof运算时会递归查找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。
运算符右边只是找出了 右边操作数的prototype是什么。
所以一句话总结:instanceof 检测 左侧操作数 的__proto__原型链上,是否存在右侧的prototype原型。
以上这些看似很有道理,事实上也的确如此。但是Object 和 Function 的关系到底如何?
2、JavaScript的构造器Function 和 Object
首先明白两点 1)__proto__(原型链属性)是JavaScript中一切对象都有的属性,它一般指向创建它的函数的prototype属性(原型)有一点例外(不用函数创建对象,用var a = {}; var b = Object.create(a); 此时,b.__proto__ 指向a 而不是a.prototype,因为a是用字面值创建的对象,没有prototype属性。
2)prototype 是只有函数对象才有的属性。它的指向一般是
最重要的一点Function.prototype.construtor指向它本身,Object.prototype.construtor也指向Function。
从这里可以说,所有的对象都是由Function生成的。
结论:构造器的原型链是封闭的,它借由一个匿名函数实现。即, Function.__proto__指向一个匿名函数function(){} ,匿名函数的__proto__指向Object的prototype ,Object的__proto__指向Function 的 prototype.