JS - 创建 Hello World 函数

23 阅读5分钟

题目描述

请你编写一个名为 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 个主要区别。

  1. 更简洁的语法。对于匿名函数和单行函数来说尤其如此。因此,在将短的匿名函数传递给其他函数时,通常优先使用这种方式。
  2. 没有自动提升。只有在声明后才能使用函数。这通常被认为有助于提升可读性。
  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";
};