DrillLab
第 24 / 105 道24 / 105 · #285

有几种定义函数的方式

How many ways to define a function

先自己答,再往下看Answer it yourself first

一句话:五种 —— 函数声明、函数表达式、箭头函数、Function 构造器、以及对象/类里的方法简写。

但面试真正想听的是它们的差别, 尤其是前三种:

提升thisarguments能否 new
函数声明整体提升,声明前可调用调用时决定
函数表达式只提升变量名调用时决定
箭头函数只提升变量名定义时的外层 this没有不能

箭头函数不是「更短的 function」—— 它没有自己的 this、 没有 arguments、 不能当构造器、没有 prototype。 所以对象方法里想用this 指向该对象,就不能用箭头函数

会追问:Function 构造器为什么不用?」—— 它接收字符串当函数体,相当于 eval: 有注入风险、拿不到闭包、 而且引擎没法优化。知道它存在但说明不该用就是正确答案。

In one line: five — function declaration, function expression, arrow function, the Function constructor, and method shorthand inside an object or class.

But what the interview actually wants is the differences, especially between the first three:

HoistingthisargumentsCan you new it
Function declarationHoisted whole, callable before its lineDecided at call timeYesYes
Function expressionOnly the variable name is hoistedDecided at call timeYesYes
Arrow functionOnly the variable name is hoistedThe enclosing this where it was writtenNoNo

An arrow function is not “a shorter function” — it has no this of its own, no arguments, cannot be a constructor, and has no prototype. So if an object method needs this to be that object, it cannot be an arrow function.

Follow-up: “Why does nobody use the Function constructor?” — it takes the body as a string, which makes it eval in disguise: an injection risk, no access to the surrounding closure, and nothing the engine can optimise. Knowing it exists and saying it should not be used is the right answer.

JavaScript三种写法的实际差别How the three forms actually differ示意Illustrative
1sayHi(); // ✓ 能跑 —— 函数声明整体提升
2function sayHi() { console.log("hi"); }
3
4sayHey(); // ✗ TypeError: sayHey is not a function
5var sayHey = function () {}; // 只提升了变量名,此刻还是 undefined
6
7// 箭头函数的 this 是定义时的外层 this
8const obj = {
9 name: "A",
10 arrow: () => console.log(this.name), // undefined ← 外层是模块/window
11 normal() { console.log(this.name); }, // "A" ← 调用时决定
12};
1sayHi(); // ✓ runs —— a function declaration is hoisted whole
2function sayHi() { console.log("hi"); }
3
4sayHey(); // ✗ TypeError: sayHey is not a function
5var sayHey = function () {}; // only the name was hoisted; it is still undefined here
6
7// An arrow function's this is the outer this at the place it was defined
8const obj = {
9 name: "A",
10 arrow: () => console.log(this.name), // undefined ← the outside is the module/window
11 normal() { console.log(this.name); }, // "A" ← decided at call time
12};