Function 对象与 Normal 对象有何不同?

How are Function objects different from Normal objects?

函数如何存储在变量中?

根据MDN

In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.

假设这样的场景,

var fn = function () {};
fn.attr = 3;

console.log(fn); //prints function() {}

console.log(Object.keys(fn)); //prints ["attr"]

如果一个函数是一个对象,它不应该有键和值类型,函数存储在 属性 中并且解释器不显示 属性 吗?类似于 C++ 风格的运算符重载或 Javascript 本身中的 array/object 表示。我的意思是说函数(或数组)只是以不同方式处理的对象吗?这可能意味着匿名函数存储在具有隐藏 属性.

的对象中

总而言之,函数(或数组)的基本工作原理是什么?他们有特殊待遇吗?或者它们只是一些隐藏的 属性 的语法糖,当使用 () 时调用?

是的,功能比较特殊

证明

const f = Object.create(Function.prototype);
f(); // TypeError: f is not a function

博览会

它们 "callable objects" 只能通过规定的语法创建(函数表达式、语句、声明、粗箭头、对象文字方法定义 shorthand、Function 构造函数、class 方法)。

这意味着它们有一个特殊的 [[Call]] 方法(您看不到),当您使用 () 语法调用它们时会调用该方法。

[[Call]]坐标:

  • 创建执行上下文(调用堆栈框架)
  • 将新的执行上下文添加到堆栈顶部
  • 函数逻辑的执行
  • 从堆栈中删除执行上下文
  • 将下一个上下文定位到 运行(堆栈中紧靠下方的上下文)
  • 向下一个执行上下文提供任何 return 值

执行上下文的创建依次完成 LexicalEnvironment(用于范围界定)的配置、函数和其他元逻辑的接收器配置 (this)。

函数也不同于大多数普通对象,因为它们在 [[Prototype]] 链上有 Function.prototype(尽管您可以通过继承 Function.prototype 创建自己的 'useless' 对象- 见上文)。

有关差异的完整列表,请参阅 MDN, the spec