最近看javascript权威指南,感觉自己以前对javascript认识的太过于肤浅。有好多方面,很欠缺。比如对作用域来说。
大家都知道一个变量的作用域(scope)是程序中定义这个变量的区域。全局(global)变量的作用域是全局性的,在javascript中,它的存在都有定义。而在函数之内声明的变量,就只在函数体内部有定义。它们是局部(local)变量,作用域是全局性的。函数的参数也是局部变量,它们只在函数体内部有定义。
在函数体内部,局部变量的优先级比同名的全局变量高。比如给一个局部变量或者函数的参数声明的名字与某个全局变量名字一样的话,那么引用的就是那个局部变量或者函数的参数声明啦,间接隐藏了那个全局变量
var scope=”jquery”;
function checkscope(){
var scope=”javascript”;
alert(scope);
}
checkscope();
上面的代码就是显示alert出javascript,之前定义的全局变量jquery有效的被隐藏。
但是如果一个函数定义嵌套在另外一个函数中,那么嵌套的函数中有声明的变量就具有嵌套的局部作用域。当然我们知道全局变量是全局对象的属性,而局部变量是一个特殊的调用对象的属性,那么我们就可以再次关注一下变量作用域的表示法,对它进行再定义。有关作用域的新描述给理解多环境下的变量提供了一种有用的方法,它为javascript的工作过程提供了一个强大的新理解。
每个javascript执行环境都有一个和它关联在一起的作用域链(scope chain).这个作用域链是一个对象列表或对象链。当javascript需要查询变量x的值时,它就开始查看该链的第一个对象。如果那个对象有一个叫x的属性,那么就采用这个属性的值。要是第一个对象没有叫x的属性,那么继续查询链中的第二个对象。如果第二个没有继续查,依次类推。
转自http://www.jqueryba.com/68.html
### 深入理解变量作用域
#### 一、引言
在JavaScript编程语言中,作用域是一个核心概念,它决定了变量的可见性和生命周期。作用域不仅影响着代码的执行效率,更是解决bug的关键所在。本文将从JavaScript权威指南出发,深入探讨变量作用域的相关知识点,包括全局作用域、局部作用域、以及闭包等高级概念。
#### 二、全局作用域与局部作用域
1. **全局作用域**
- 定义:在JavaScript中,如果一个变量在任何函数外部声明,则该变量处于全局作用域下。这意味着它可以在程序的任何地方被访问。
- 特性:
- 全局变量在整个程序运行期间都是可用的。
- 当一个变量被声明但未被赋值时,默认值为`undefined`。
- 全局变量通常被视为“公共”的,因此应当谨慎使用以避免潜在的命名冲突。
2. **局部作用域**
- 定义:当一个变量在函数内部声明时,该变量仅在该函数内有效,这就是局部作用域。
- 特性:
- 函数内部声明的变量不会污染全局命名空间。
- 如果函数内部声明的变量与全局变量同名,局部变量会覆盖全局变量。
- 局部变量在其函数执行完毕后会被销毁(除非涉及闭包)。
#### 三、作用域链
1. **作用域链的概念**
- 在JavaScript中,每个执行上下文都有一个与之相关联的作用域链。作用域链是一个对象列表,用于存储变量和函数声明。
- 当JavaScript引擎需要查找变量时,它会从当前作用域开始,沿着作用域链向上查找,直到找到相应的变量为止。
- 如果在当前作用域找不到变量,则继续在上一层作用域中查找,依此类推,直到到达全局作用域。
- 这个查找过程确保了变量的正确访问顺序,并避免了命名冲突。
2. **示例解析**
```javascript
var scope = "jQuery";
function checkScope() {
var scope = "JavaScript";
alert(scope); // 输出 "JavaScript"
}
checkScope(); // 调用函数
```
- 上述代码展示了作用域链的工作原理。当`checkScope`函数执行时,其内部的`scope`变量优先于全局的`scope`变量。因此,即使全局有一个名为`scope`的变量,但在`checkScope`函数内部,仍然会输出局部变量`scope`的值。
#### 四、闭包
1. **闭包的概念**
- 闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包最常见的方法是函数嵌套。
- 闭包使得函数可以访问并操作外部函数中的变量,即使外部函数已经返回。
- 闭包对于保持数据私密性和实现模块化非常有用。
2. **闭包的例子**
```javascript
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log("outerVariable: ", outerVariable);
console.log("innerVariable: ", innerVariable);
};
}
const myFunction = outerFunction("Hello");
myFunction("World"); // 输出: "outerVariable: Hello", "innerVariable: World"
```
- 在这个例子中,`innerFunction`是一个闭包,它可以访问`outerFunction`中的`outerVariable`。即使`outerFunction`已经执行完毕并返回,`innerFunction`仍然能够访问到`outerVariable`。
#### 五、总结
通过本文的介绍,我们可以看出变量作用域在JavaScript中的重要性。无论是全局作用域还是局部作用域,都直接影响着代码的行为。此外,理解作用域链和闭包的概念对于编写高质量、可维护的JavaScript代码至关重要。掌握这些知识点有助于开发者更好地管理变量的作用范围,避免潜在的问题,提高代码的质量和性能。