<SCRIPT LANGUAGE="JavaScript">
var bb = 1;
function aa(bb) {
bb = 2;
alert(bb);
};
aa(bb);
alert(bb);
</SCRIPT>
输出:2,1。
这段代码考察了以下几个关键的 JavaScript 知识点:
1. 变量作用域(Scope)
-
全局变量与局部变量:
- 代码中的
var bb = 1;声明了一个全局变量bb,它在整个脚本的范围内都可以访问。 - 在函数
aa中,bb被当作函数参数传入,这个bb变量是局部变量,函数内部的bb与全局变量bb是相互独立的。即使局部变量的名字和全局变量相同,它们还是在不同的作用域中,不会相互干扰。
- 代码中的
2. 参数传递(Pass by Value)
-
按值传递:
- 在 JavaScript 中,基本类型(如数字、字符串、布尔值等)的函数参数是按值传递的。这意味着当你将一个变量传递给函数时,传递的是该变量值的副本。
- 在这段代码中,
aa(bb)调用时,全局变量bb的值1被复制并传递给函数aa。因此,aa函数内的bb是这个副本,与全局变量bb无关。 - 当函数内部修改
bb时,只是修改了副本,而不影响全局作用域的bb。
3. 函数作用域与变量遮蔽(Shadowing)
-
变量遮蔽:
- 当函数的参数名与外部作用域(如全局作用域)中的变量名相同时,函数内的局部变量会“遮蔽”外部变量,导致在函数内部无法直接访问外部变量。
- 在这段代码中,函数参数
bb与全局变量bb名字相同,函数内对bb的操作只影响函数内部的bb(即参数的副本),而不会影响全局的bb。
作用域链 是 JavaScript 中的一种机制,用于解析变量的访问顺序。它定义了在不同的作用域(scope)中,变量和函数的可访问性及查找顺序。
作用域和作用域链的基本概念
-
作用域(Scope) :
-
作用域是指程序中变量、函数等标识符的可访问范围。在 JavaScript 中,作用域主要分为以下几种:
- 全局作用域:在代码的任何地方都能访问的作用域,通常是最外层定义的变量或在
window对象上定义的变量。 - 函数作用域:在函数内部定义的变量和函数只能在该函数内部访问。
- 块级作用域:使用
let、const等在块级(如{})中定义的变量,只能在该块级作用域内访问。
- 全局作用域:在代码的任何地方都能访问的作用域,通常是最外层定义的变量或在
-
-
作用域链(Scope Chain) :
- 作用域链是一个指向变量对象的指针列表,当 JavaScript 引擎尝试查找一个变量时,它会从当前作用域开始查找。如果找不到,它会沿着作用域链向上查找,直到找到该变量或到达全局作用域。
- 这种从当前作用域到全局作用域逐级向上查找的过程,就是作用域链的工作机制。
作用域链的工作原理
当你在代码中访问一个变量时,JavaScript 引擎会按照以下顺序查找变量:
- 当前作用域:首先引擎会在当前作用域中查找变量。
- 上级作用域:如果当前作用域没有找到该变量,查找会继续在上一级作用域进行。
- 全局作用域:如果上级作用域中仍未找到变量,查找最终会到达全局作用域。
- 未找到:如果在全局作用域中也找不到该变量,JavaScript 引擎会抛出
ReferenceError错误。
示例代码
let globalVar = "global";
function outerFunction() {
let outerVar = "outer";
function innerFunction() {
let innerVar = "inner";
console.log(innerVar); // 输出 "inner"
console.log(outerVar); // 输出 "outer"
console.log(globalVar); // 输出 "global"
}
innerFunction();
}
outerFunction();
在这个例子中:
innerFunction函数首先在其自身作用域内查找innerVar,找到了并输出 "inner"。- 对于
outerVar,innerFunction在其自身作用域内未找到,于是沿着作用域链查找到了outerFunction的作用域,并成功找到了outerVar,输出 "outer"。 - 对于
globalVar,innerFunction沿着作用域链找到了全局作用域中的变量globalVar,输出 "global"。
作用域链的意义
- 变量遮蔽(变量隐藏) :如果在当前作用域中定义了一个与上级作用域同名的变量,那么上级作用域中的变量在当前作用域中将被遮蔽。即,当前作用域中的同名变量将优先被访问。
- 闭包:JavaScript 中的闭包利用了作用域链的机制,使得内部函数可以访问其外部函数作用域中的变量。
总结
- 作用域链 是 JavaScript 中的一种变量解析机制,它决定了变量在不同作用域中的可访问性。
- 查找变量时,JavaScript 引擎会从当前作用域开始,沿着作用域链向上查找,直到找到变量或到达全局作用域。
- 作用域链确保了代码的结构性和可预测性,使得变量查找有序进行