当我执行代码时:
console.log(Function.prototype);
它返回:
function Empty() {}
(至少在 Chrome 中)
为什么会这样?我的印象是原型几乎总是直接的对象文字,而且我检查过的几乎所有其他地方似乎都是这种情况。我很好奇为什么 Function.prototype 解析为不同的东西。
当我执行代码时:
console.log(Function.prototype);
它返回:
function Empty() {}
(至少在 Chrome 中)
为什么会这样?我的印象是原型几乎总是直接的对象文字,而且我检查过的几乎所有其他地方似乎都是这种情况。我很好奇为什么 Function.prototype 解析为不同的东西。
Because that is what ECMAScript 5 requires.
15.3.4 Properties of the Function Prototype Object
The
Function
prototype object is itself a Function object (its[[Class]]
is "Function") that, when invoked, accepts any arguments and returnsundefined
.
Most (or all?) other native constructors have prototypes defined as the same type of object that is produced.
Considering that the prototype object holds the methods for that type, it makes sense that those methods should function properly when called on that object.
首先注意一个对象的实际原型,就像一个对象继承行为的东西一样,存储在它的 __proto__ 属性中(在大多数实现中 - thx @thesystem)。Function 对象的“原型”属性是它自己的 __proto__,它是特殊的内置函数字面量单例对象function(){}
(Chrome 的 console.log()function Empty() {}
无论出于何种原因都必须打印它,但它是一样的)。由于所有函数都是对象(但并非所有对象都是函数),因此该对象的 __proto__ 是另一个特殊的内置文字单例对象[object Object]
。[object Object]
__proto__ 为空。[object Object]
是原型链的根。
检查它的输出显示了事情是如何安排的(可从命令行解释器运行)。
print( Function.prototype === Function.__proto__ );
var f = new Funtion();
print( f.__proto__ === Function.prototype );
print( f.__proto__ );
print( f.__proto__.__proto__ );
print( f.__proto__.__proto__.proto__ );
现在,内置的 JavaScript 对象有一个名为“类”的属性。此属性是不可变的,由 JavaScript 引擎本身设置。JavaScript 将该类用于特殊的内部目的。Javascript 需要知道这一点,因此它知道可以调用 Function 对象(如 @thesystem 给出的先前答案的链接中所暗示的那样 - http://es5.github.com/#x15.3.4)。从规范:
“[[Class]] 内部属性的值由本规范为每种内置对象定义。宿主对象的 [[Class]] 内部属性的值可以是任何字符串值,除了“参数”、“数组”、“布尔”、“日期”、“错误”、“函数”、“JSON”、“数学”、“数字”、“对象”、“正则表达式”和“字符串”。值[[Class]] 的内部属性在内部用于区分不同种类的对象。请注意,本规范不提供程序访问该值的任何方法,除非通过 Object.prototype.toString(参见 15.2.4.2)。- http://es5.github.com/#x8.6.2
Function 对象的原型 AKA 的“类”function(){}
是“Function”。Function 的类也是“Function”。当一个新对象被创建时,Javascript 直接根据其构造函数的类属性设置它的类属性,这在对象的生命周期内是不可变的。