一、什么是作用域?
作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性,作用域决定了代码区块中变量和其他资源的可见性。下面我们通过一个例子来理解下作用域这个概念 :
function scope() {
var insideVariable = 'insideVariable';
}
scope();
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined
这段代码在浏览器运行之后会抛出引用错误 , 原因是因为我们的变量 insideVariable 在全局作用域并没有声明 , 所以在全局作用域下取值会报错。这里我们引伸出了 全局作用域 这个概念。
在 js 中我们的作用域分为:
- 全局作用域
- 局部作用域
- 块级作用域
a 、全局作用域
什么是全局作用域 : 在代码中任何地方都能访问到的对象拥有全局作用域。
js 中一般有以下三种情形拥有全局作用域 :
1. 所有 window 对象的属性拥有全局作用域
console.log(window);
在浏览器中打印我们的 window 对象之后如下图所示 :
如图所示所有 window 对象的属性都拥有全局作用域 , 标红部分即是我们常用的一些全局作用域的函数。之所以我们可以在一段 js 代码中直接使用 alert 函数 , 就是因为它被定义在了我们的window 对象上 , 而window 对象的属性都拥有全局作用域
1. 在最外层定义的变量 , 函数 , 及对象。
var globalVariable = 'globalVariable'; // 最外层变量
function globalFunction() {
// 最外层函数
var currentVariable = 'current_variable'; // 函数内变量
function currentFunction() {
// 函数内函数
console.log(currentVariable);
}
console.log(globalVariable);
}
console.log(globalVariable); // globalVariable
globalFunction(); // globalVariable
console.log(currentVariable); // currentVariable is not defined
console.log(currentFunction); // currentFunction is not defined
如上例子中我们的globalVariable和globalFunction 拥有全局作用域,所以在任何地方都可以访问到,但是内部的currentVariable和currentFunction定义在 globalFunction 函数的局部作用域中所以在全
局作用域无法访问。
2. 所有未定义直接赋值的变量自动声明为全局作用域
function scope() {
globalVariable = 'globalVariable'; // 未定义直接赋值的变量
}
scope();
console.log(globalVariable); // globalVariable
本例子中globalVariable便是我们的未定义直接赋值的变量 , 它同样具有我们全局作用域 , 而且我们的 globalVariable 会直接挂到 window 对象上 , 虽然这种操作代码可以正常运行但却很可能会污染全局作用域空间。一般不推荐使用。
b 、局部作用域
局部作用域指的就是我们的函数作用域 , 代指函数内部的空间。函数内部空间声明的变量无法在外部访问 , 例如 :
function doSomething() {
var currentName = 'xiaohong';
}
doSomething();
console.log(currentName); // currentName is not defined
c 、块级作用域
块级作用域是指被大括号 ("{}") 包裹住的相关联的语句的集合。例如 , 你可以在 if 后声明一段函数块形式的代码,表明当条件判断为真时,解释程序应该运行上述函数块里的代码,或者当条件判断为假时跳过执行上述函数块里的代码。如下 :
// 1. if 语句中的块级作用域 , if 语句后面的 {} 中便是我们的块级作用域
let isPay = false;
if (isPay) {
console.log('payment success');
}
// 2. 直接使用 {} 块级作用域。
let a = 1;
{
let a = 2;
}
console.log(a); // 1
二、什么是作用域链?
当我们在某个函数的内部作用域中查找某个变量时 , 如果没有找到就会到他的父级作用域中查找 , 如果父级也没找到就会接着一层一层的向上寻找,直到找到全局作用域还是没找到的话,就宣布放弃。这种一层一层的作用域嵌套关系,就是 作用域链 , 举个例子 :
var a = 100;
function globalFunc() {
var b = 200;
function currentFunc() {
var c = 300;
console.log(a); // 全局作用域的变量
}
currentFunc();
}
globalFunc();
如上例子中当我们在 currentFunc 中查找 a 变量的时候 当前 currentFunc 作用域不存在所以就到他的父作用域 globalFunc 中查找,同样还是没找到 , 在往上就到了我们的全局作用域, 在全局作用域找到了我们需要的变量 a 。 可以看到这个查找的过程就是顺着我们的 作用域链 层层往上的。
- 什么是作用域?
作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性,作用域决定了代码区块中变量和其他资源的可见性。
- 作用域存在的意义是什么?
作用域存在的最大意义就是 变量隔离 , 即 : 不同作用域下同名变量不会有冲突。
- 什么是作用域链?
当我们在某个函数的内部作用域中查找某个变量时 , 如果没有找到就会到他的父级作用域中查找 , 如果父级也没找到就会接着一层一层的向上寻找,直到找到全局作用域还是没找到的话,就宣布放
弃。这种一层一层的作用域嵌套关系,就是 作用域链 。