题目描述
请你编写一个名为 createHelloWorld
的函数。它应该返回一个新的函数,该函数总是返回 "Hello World"
。
示例 1:
输入: args = []
输出: "Hello World"
解释:
const f = createHelloWorld();
f(); // "Hello World"
createHelloWorld 返回的函数应始终返回 "Hello World"。
示例 2:
输入: args = [{},null,42]
输出: "Hello World"
解释:
const f = createHelloWorld();
f({}, null, 42); // "Hello World"
可以传递任何参数给函数,但它应始终返回 "Hello World"。
题解
JavaScript 函数基础
这个问题旨在介绍 JavaScript 函数。本文将涵盖函数的语法以及 闭包 和 高阶函数 等相关主题。
如果你是 JavaScript 的新手,建议你跟随代码示例一起学习。你可以在 LeetCode 的 30 天 JavaScript 挑战 的学习计划中完成 JavaScript 的入门学习。
JavaScript 有一个很棒的特性是浏览器初始就内置了执行环境。你可以在 此处 阅读有关如何在浏览器中执行代码(以及查看网站代码)的更多信息。
函数语法
在 JavaScript 中,有两种主要声明函数的方式,其中之一是使用 function
关键字。
基本语法
语法如下:
function f(a, b) {
const sum = a + b;
return sum;
}
console.log(f(3, 4)); // 7
在这个示例中, f
是函数的名称。 (a, b)
是参数。你可以在函数体中编写任何逻辑,最后返回一个结果。你也可以返回 undefined
,它将隐式返回。
匿名函数
你可以选择在 function
关键字后面省略函数的名称。
var f = function(a, b) {
const sum = a + b;
return sum;
}
console.log(f(3, 4)); // 7
立即调用的函数表达式 (IIFE)
你可以在 JavaScript 中创建一个函数并立即执行它。
const result = (function(a, b) {
const sum = a + b;
return sum;
})(3, 4);
console.log(result); // 7
为什么要这样编写代码?这样做可以把变量 封装 在新的 作用域 内。如果这样做,另一个开发人员就可以立即了解到 sum
无法在函数体外部的任何地方使用。
函数内的函数
JavaScript 的一个强大特性是你可以直接在其他函数内创建函数,并且反复调用。
function createFunction() {
function f(a, b) {
const sum = a + b;
return sum;
}
return f;
}
const f = createFunction();
console.log(f(3, 4)); // 7
在这个示例中,createFunction()
返回了一个新的函数。然后该函数就可以像普通函数一样使用。
函数提升
JavaScript 具有一个称为 *提升(hoisting) * 的功能,其中函数有时可以在初始化之前使用。只有在使用 function
语法声明函数时才能这样做。
function createFunction() {
return f;
function f(a, b) {
const sum = a + b;
return sum;
}
}
const f = createFunction();
console.log(f(3, 4)); // 7
在这个示例中,函数在初始化之前被返回。虽然这是有效的语法,但有时会被认为是不好的写法,因为它可能会降低代码的可读性。
闭包
JavaScript 中一个重要的主题是闭包的概念。当创建函数时,它可以访问其周围声明的所有变量,也被称为词法环境。函数和其环境的组合称为闭包。这是该语言中一个强大且常用的特性。
function createAdder(a) {
function f(b) {
const sum = a + b;
return sum;
}
return f;
}
const f = createAdder(3);
console.log(f(4)); // 7
在这个示例中,createAdder
传递第一个参数 a
,而内部函数可以访问它。这样,createAdder
充当了新函数的工厂,每个返回的函数具有不同的行为。
箭头函数语法
另一种常见的声明函数的方式是使用箭头语法。实际上,在许多项目中,这都是首选的语法。
基本语法
const f = (a, b) => {
const sum = a + b;
return sum;
};
console.log(f(3, 4)); // 7
在这个示例中,f
是函数的名称。(a, b)
是参数。你可以在函数体中编写任何逻辑,最后返回一个结果。你也可以选择返回 undefined
,在这种情况下 undefined
将隐式返回。
省略 return
如果你的代码可以编写在一行中,你可以省略 return
关键字。这可以让我们得到非常简短的代码。
const f = (a, b) => a + b;
console.log(f(3, 4)); // 7
差异
箭头语法和函数语法之间有 3 个主要区别。
- 更简洁的语法。对于匿名函数和单行函数来说尤其如此。因此,在将短的匿名函数传递给其他函数时,通常优先使用这种方式。
- 没有自动提升。只有在声明后才能使用函数。这通常被认为有助于提升可读性。
- 不能绑定到
this
、super
和arguments
,也不能用作构造函数。这些都是复杂的主题,但基本结论应该是箭头函数在其特性集方面更简单。你可以在 此处 阅读更多有关这些差异的信息。
箭头语法与函数语法的选择主要取决于个人偏好和项目的样式标准。
剩余参数
你可以使用 剩余 语法来将所有传递的参数作为数组访问。这对于此问题并不是必需的,但对于许多其他问题来说,这是一个关键概念。你可以在 此处 阅读有关 ...
语法的更多信息。
基本语法
语法如下:
function f(...args) {
const sum = args[0] + args[1];
return sum;
}
console.log(f(3, 4)); // 7
在这个示例中,变量 args
是 [3, 4]
。
为什么使用剩余参数
这个语法的用途可能并不明显,因为你总是可以通过传递一个数组获得相同的结果。
剩余参数的主要用途是创建通用的工厂函数,接受任何函数作为输入,并返回带有特定修改的新版本函数。
另外,接受函数并/或返回函数的函数称为 高阶函数 ,它们在 JavaScript 中非常常见。
例如,你可以创建一个记录日志的函数工厂:
function log(inputFunction) {
return function(...args) {
console.log("输入", args);
const result = inputFunction(...args);
console.log("输出", result);
return result;
}
}
const f = log((a, b) => a + b);
f(1, 2); // 输出:输入 [1, 2] 输出 3
问题的解决方案
现在让我们看看如何应用这些不同的 JavaScript 函数编写方式来解决这个问题。
函数语法
var createHelloWorld = function() {
return function() {
return "Hello World";
}
};
var createHelloWorld = function() {
return function(): string {
return "Hello World";
}
};
箭头语法
var createHelloWorld = function() {
return () => "Hello World";
};
var createHelloWorld = function() {
return () => "Hello World";
};
箭头语法 + 剩余参数
var createHelloWorld = function() {
return (...args) => "Hello World";
};
var createHelloWorld = function() {
return (...args: any[]) => "Hello World";
};