红宝书阅读笔记:函数(3)
2023-12-06 02:51:42
正文
1. arguments.callee
arguments.callee 是一个指向正在执行函数的指针。这允许您从函数内部调用自身,从而实现递归或创建闭包。例如,编写阶乘函数时,可以使用 return num * arguments.callee(num-1)
的表达式。
function factorial(num) {
if (num === 0) {
return 1;
} else {
return num * arguments.callee(num-1);
}
}
console.log(factorial(5)); // 输出: 120
注意: 在严格模式下访问 arguments.callee
会出错。此时,可以使用命名函数表达式来达到相同目的。
const factorial = function(num) {
if (num === 0) {
return 1;
} else {
return num * factorial(num-1);
}
};
console.log(factorial(5)); // 输出: 120
2. 闭包
闭包是指引用了另一个函数作用域中变量的函数。当一个函数被另一个函数调用时,它将创建一个新的词法环境,并将父函数的词法环境存储在内部。这允许内部函数访问父函数的作用域,即使父函数已经执行完毕。
闭包常用于创建私有变量、实现模块化和封装。
function createCounter() {
let count = 0;
return function() {
return count++;
};
}
const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1()); // 输出: 0
console.log(counter1()); // 输出: 1
console.log(counter2()); // 输出: 0
在这个例子中,createCounter
函数创建了一个闭包,其中包含一个私有变量 count
。counter1
和 counter2
都是 createCounter
函数的实例,它们都引用了相同的闭包,因此它们都可以访问 count
变量。
3. 作用域
作用域是函数或代码块可以访问的变量和函数的集合。JavaScript 具有两种主要的作用域:
- 全局作用域: 这是脚本中所有代码都可以访问的作用域。全局变量在全局作用域中声明。
- 局部作用域: 这是函数或代码块内部的作用域。局部变量在局部作用域中声明。
局部变量只能在声明它们的函数或代码块内部访问。全局变量可以在任何地方访问。
let globalVariable = 10;
function myFunction() {
let localVariable = 20;
console.log(globalVariable); // 输出: 10
console.log(localVariable); // 输出: 20
}
myFunction();
console.log(globalVariable); // 输出: 10
console.log(localVariable); // 输出: ReferenceError: localVariable is not defined
4. 词法环境
词法环境是一个函数或代码块可以访问的变量和函数的集合,包括该函数或代码块内部声明的变量和函数,以及父函数或代码块的词法环境。
词法环境决定了函数或代码块可以访问哪些变量和函数。词法环境在函数或代码块创建时确定,并在其执行期间保持不变。
function createCounter() {
let count = 0;
return function() {
return count++;
};
}
const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1()); // 输出: 0
console.log(counter1()); // 输出: 1
console.log(counter2()); // 输出: 0
在这个例子中,createCounter
函数创建了一个闭包,其中包含一个私有变量 count
。counter1
和 counter2
都是 createCounter
函数的实例,它们都引用了相同的闭包,因此它们都可以访问 count
变量。
词法环境决定了 counter1
和 counter2
可以访问哪些变量和函数。在 createCounter
函数内部创建的 count
变量在闭包中是私有的,因此 counter1
和 counter2
不能直接访问它。但是,count
变量可以通过闭包中返回的函数访问。
5. this
this
是指函数执行时的上下文对象。它可以是全局对象、函数对象或其他对象。
this
的值由函数的调用方式决定。在以下情况下,this
的值为全局对象:
- 函数在全局作用域中调用
- 函数作为回调函数被调用
- 函数使用
bind()
、call()
或apply()
方法调用
在以下情况下,this
的值为函数对象:
- 函数作为构造函数被调用
在以下情况下,this
的值为其他对象:
- 函数作为该对象的方法被调用
function myFunction() {
console.log(this);
}
myFunction(); // 输出: Window { ... }
const object = {
myFunction: function() {
console.log(this);
}
};
object.myFunction(); // 输出: { myFunction: [Function: myFunction] }
总结
本文探讨了函数(3)的知识点,包括 arguments.callee
、闭包、作用域、词法环境和 this
的概念和用法。通过提供清晰易懂的示例代码和案例解析,帮助读者全面掌握函数的奥秘。