功能真的是一个对象吗?

3
我是一个自学的Web开发者,仍在努力掌握一些JavaScript的基础知识。以下是从Douglas Crockford的《JavaScript语言精粹》中摘录的一些引用。
“JavaScript中的函数是对象。”
“在JavaScript中,数组是对象,函数是对象,正则表达式是对象,当然,对象也是对象。”
“每个对象都链接到一个原型对象,可以从中继承属性”(即构造函数、toString等)。
“如果函数是一个对象,那么为什么……”
 console.log(typeof Function);  // function 

它的类型是函数而不是对象。
 console.log(Object.constructor);  // Function()

这是它“父类”的构造函数吗?
 console.log(Function.constructor);  // Function()

“困惑了,那么构造函数实际上是一个函数?”
 console.log(typeof Function.prototype); // Function

它的原型类型是一个函数而不是一个对象吗?我以为它是从Object继承来的。
回答这些问题将极大地帮助我理解JavaScript。
5个回答

9
如果 Function 是一个对象,那么为什么它的类型是函数而不是对象呢?
因为 typeof 运算符是这样定义的,可能是为了方便使用:
- Object(原生且未实现 [[Call]])返回 "object" - Object(原生或宿主且实现了[[Call]])返回 "function" - Object(宿主且未实现 [[Call]])返回一个特定于实现的值,该值可能不是 "undefined"、"boolean"、"number" 或 "string"。
[[Call]] 是标识对象为函数(可调用)的内部属性。非本机对象是由宿主(如浏览器)提供的对象,例如 DOM 对象或 ActiveXObject 的实例。
困惑的是,构造函数实际上就是一个函数?
为什么不呢?构造函数就是函数。只能使用函数来构建实例。Object.constructor 是一个函数,但它也是一个对象。请参阅以下内容:
console.log((function () { }) instanceof Object);
//-> true

此外,根据ECMAScript规范:
每个内置函数和每个内置构造函数都有一个Function原型对象,它是表达式Function.prototype(15.3.4)的初始值,作为其[[Prototype]]内部属性的值。
除非另有规定,否则每个内置原型对象都具有Object原型对象,它是表达式Object.prototype(15.2.4)的初始值,作为其[[Prototype]]内部属性的值,但不包括Object原型对象本身。
此外,为了回答你最后的困惑:
Function原型对象本身是一个Function对象(其[[Class]]为“Function”),当调用时,接受任何参数并返回undefined。

1
+1 感谢您的解释,它确实让事情更加清晰。 - Q_Mlilo

5
当我们说“函数是一个对象”时,我们的意思并不是“是”代替了其他什么词,而是和“猫是动物”一样的意思。如果有人问你养了什么宠物,你不会回答“动物”。如果typeof总是返回object,那它就没有用处了。
函数是一个对象,但这对于typeof来说并不是一个有趣的返回值,因为它是语言本身的静态特性,不需要在运行时报告。

1
< p > 如果 typeof 运算符总是返回 "object",那它就没什么用了,不是吗?一切都是对象,但也可以是其他东西。例如,字符串是一个对象,但它也是一个字符串 :) 该运算符返回最具体类型的名称,而不是最通用的类型。这应该解释了为什么 typeof Function 是 "function"。

至于 constructor 属性,构造函数是由运算符 new 在创建对象时调用的函数。它始终是一个函数,无论对象本身是 ObjectFunction 还是其他什么。


2
原始类型 - 字符串、数字和布尔值 - 不是对象,但当您尝试访问它们的对象对应项的属性或方法时,它们会被隐式转换为对象。例如,"jim" instanceof Object 将返回 false,但 new String("jim") instanceof Object 将返回 true。 - Andy E

0

参考 每个JavaScript对象都是函数吗?

javascript:alert([ window.navigator.userAgent, Object, Function ].join("\n\n") )

显示

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 
      Ubuntu/10.04 (lucid) Firefox/3.6.3

function Object() {
    [native code]
}

function Function() {
    [native code]
}

同样

javascript:alert([ new Object, new Function ].join("\n\n") )

显示

[object Object]

function anonymous() {  }

并且

javascript:alert([ new new Function ].join("\n\n") )

显示

[object Object]

0

console.log(typeof Function); 显示该对象的类型为 Function 而不是 object

举个例子:

function squareValue(var x) {
    return x * x;
}

可以简单地翻译为

var squareValue = new Function("x", "return x*x");

因此,执行

var valueSquared = squareValue(x);

在这两个例子中,将产生相同的结果...

这就是为什么Javascript中的每个函数都是一个Function对象。

Javascript对象/函数上的.constructor.prototype.toString都是它们各自对象中的函数,因此你会得到"function"的输出。

这是基于ECMA-262第3版-1999年12月的规定。

希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接