这道题主要考察大家对 闭包 的理解
什么是闭包?怎么实现闭包?
闭包(closure) 是指有权访问另一个函数作用域中的变量的函数,也可以这么理解(函数在其定义的词法作用域之外被调用时,依然能够访问该作用域内变量的特性)。可以通过函数嵌套和变量引用来实现闭包。
以下实例代码中,fun函数 返回了一个 闭包fn,其中包含了count变量。由于count只在fun函数内部定义,因此外部无法直接访问它。但由于fn函数引用了count变量,因此count变量的值可以在闭包内部被修改和访问。
function fun(){
let count = 1
return function fn(){
count++
console.log(count);
}
// return fn
}
var testFun = fun()
testFun() //2
testFun() //3
testFun() //4
实现示例
使用闭包来实现一个 once
函数,确保传入的函数只执行一次。
function once(fn) {
let executed = false;
return function(...args) {
if (!executed) {
executed = true;
return fn.apply(this, args);
}
};
}
// 示例用法
var fun = once(function () {
console.log("hello world");
});
fun(); // 输出 "hello world"
fun(); // 不输出
fun(); // 不输出
解释
- 闭包:在
once
函数内部,我们定义了一个局部变量executed
,并返回一个新的函数。 - 检查和执行:返回的这个新函数会检查
executed
的值。如果executed
是false
,则执行传入的函数fn
,并将executed
设置为true
。这样可以确保fn
只会被执行一次。 - 参数传递:使用
...args
和apply
方法,确保传入的新函数能够接收任何数量的参数,并且正确地将这些参数传递给fn
。arguments
是函数内部的一个类数组对象,包含所有传递给函数的参数。apply
是一个函数方法,用于调用一个函数并传递参数数组,同时可以指定this
的值。
其他
arguments
是一个类数组对象,包含传递给函数的所有参数。apply
是一个函数方法,用于调用一个函数,并且可以指定 this
关键字的值,以及一个数组或类数组对象作为参数。
arguments
的作用
- 定义:
arguments
是一个类数组对象,包含函数调用时传递给该函数的所有参数。 - 作用:
- 可以用来访问函数的参数列表。
- 适用于需要处理不定数量参数的情况。
示例
function example() {
console.log(arguments); // 输出传递给函数的所有参数
}
example(1, 2, 3); // 输出 [1, 2, 3]
apply
的作用
- 定义:
apply
是一个函数方法,用于调用一个函数,并且可以指定this
的值,以及一个数组或类数组对象作为参数。 - 作用:
- 可以用来调用函数并传递参数数组。
- 适用于当需要将一个数组或类数组对象作为参数列表传递给函数时。
示例
function example(a, b, c) {
console.log(a, b, c);
}
const args = [1, 2, 3];
example.apply(null, args); // 输出 1 2 3
对比
-
arguments
:- 主要用于函数内部访问参数。
- 是一个类数组对象。
- 不适用于箭头函数。
-
apply
:- 用于调用函数并传递参数。
- 接受一个数组或类数组对象作为参数。
- 可以改变函数的
this
指向。
总结
这种方法利用了 JavaScript 中闭包的特性,使得函数 fn
的执行状态被封闭在 once
函数的作用域中,从而实现了只执行一次的效果。