JavaScript函数作用域深层次理解!从菜鸟到大师!
2024-01-28 16:35:30
前言
本文是由一道面试题展开的,关于Javascript函数与作用域的查遗补漏相关知识点:
- 函数
- 函数表达式 vs 函数声明
- 深入理解箭头函数
- 作用域
- 词法作用域
- 函数作用域
- 块作用域
函数
函数是JavaScript中最重要的概念之一,它允许你将代码组织成可重用的模块,以便在程序中多次调用。函数可以接受参数,并返回一个值。
函数有两种定义方式:函数表达式和函数声明。函数表达式是将函数定义为一个表达式,而函数声明是使用function
来声明函数。
// 函数表达式
const sum = function(a, b) {
return a + b;
};
// 函数声明
function sum(a, b) {
return a + b;
}
作用域
作用域是JavaScript中另一个重要的概念,它决定了变量和函数可以在程序中的哪些部分被访问。作用域可以分为词法作用域和动态作用域。
词法作用域是JavaScript中默认的作用域类型。在词法作用域中,变量和函数的作用域由它们在代码中的位置决定。这意味着变量和函数只能在它们被定义的作用域内被访问。
function outer() {
let a = 10;
function inner() {
console.log(a); // 10
}
inner();
}
outer();
在上面的例子中,变量a
的作用域是函数outer
。这意味着变量a
只能在函数outer
内部被访问。函数inner
是函数outer
的内部函数,因此它也可以访问变量a
。
动态作用域是另一种作用域类型,它不是JavaScript中的默认作用域类型。在动态作用域中,变量和函数的作用域由它们在运行时的位置决定。这意味着变量和函数可以在它们被定义的作用域之外被访问。
function outer() {
let a = 10;
function inner() {
console.log(a); // undefined
}
return inner;
}
const inner = outer();
inner();
在上面的例子中,变量a
的作用域是函数outer
。这意味着变量a
只能在函数outer
内部被访问。但是,函数inner
是在函数outer
外部调用的,因此它不能访问变量a
。
词法作用域
词法作用域是JavaScript中默认的作用域类型。在词法作用域中,变量和函数的作用域由它们在代码中的位置决定。这意味着变量和函数只能在它们被定义的作用域内被访问。
function outer() {
let a = 10;
function inner() {
console.log(a); // 10
}
inner();
}
outer();
在上面的例子中,变量a
的作用域是函数outer
。这意味着变量a
只能在函数outer
内部被访问。函数inner
是函数outer
的内部函数,因此它也可以访问变量a
。
函数作用域
函数作用域是JavaScript中另一种作用域类型。函数作用域是函数内部的作用域。这意味着变量和函数只能在它们所在的函数内部被访问。
function outer() {
let a = 10;
if (true) {
let b = 20;
console.log(a); // 10
console.log(b); // 20
}
console.log(a); // 10
console.log(b); // ReferenceError: b is not defined
}
outer();
在上面的例子中,变量a
的作用域是函数outer
。这意味着变量a
可以在函数outer
的任何地方被访问。变量b
的作用域是函数outer
内部的if
语句块。这意味着变量b
只能在if
语句块内部被访问。
块作用域
块作用域是JavaScript中最新引入的作用域类型。块作用域是花括号{}
内部的作用域。这意味着变量和函数只能在它们所在的块作用域内被访问。
function outer() {
let a = 10;
{
let b = 20;
console.log(a); // 10
console.log(b); // 20
}
console.log(a); // 10
console.log(b); // ReferenceError: b is not defined
}
outer();
在上面的例子中,变量a
的作用域是函数outer
。这意味着变量a
可以在函数outer
的任何地方被访问。变量b
的作用域是函数outer
内部的花括号{}
块。这意味着变量b
只能在花括号{}
块内部被访问。
闭包
闭包是JavaScript中的一种函数,它可以访问其定义范围之外的变量。闭包通常用于创建私有变量或实现延迟执行。
function outer() {
let a = 10;
function inner() {
console.log(a); // 10
}
return inner;
}
const inner = outer();
inner();
在上面的例子中,函数inner
是一个闭包。函数inner
可以访问其定义范围之外的变量a
。这是因为函数inner
是函数outer
的内部函数,因此它可以访问函数outer
的所有变量。
作用域链
作用域链是JavaScript中的一种数据结构,它存储了变量的作用域。作用域链是从当前执行环境开始,一直到全局作用域的变量作用域的列表。
当JavaScript解释器执行代码时,它会创建一个执行环境。执行环境包含了当前正在执行的代码、变量的作用域以及其他一些信息。
当JavaScript解释器在执行环境中找不到某个变量时,它就会沿着作用域链向上查找。如果在作用域链中找到了该变量,则JavaScript解释器就会使用该变量。如果在作用域链中找不到该变量,则JavaScript解释器就会抛出一个错误。
总结
在本文中,我们深入探究了JavaScript函数的作用域。我们学习了函数表达式、函数声明、箭头函数、作用域、词法作用域、函数作用域、块作用域、闭包和作用域链。通过这些知识,我们可以更好地理解JavaScript代码,并写出更健壮、更可靠的JavaScript程序。