作用域和作用域链

一、什么是作用域?
作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性,作用域决定了代码区块中变量和其他资源的可见性。下面我们通过一个例子来理解下作用域这个概念 :

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 。 可以看到这个查找的过程就是顺着我们的 作用域链 层层往上的。

  • 什么是作用域?

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性,作用域决定了代码区块中变量和其他资源的可见性。

  • 作用域存在的意义是什么?

作用域存在的最大意义就是 变量隔离 , 即 : 不同作用域下同名变量不会有冲突。

  • 什么是作用域链?

当我们在某个函数的内部作用域中查找某个变量时 , 如果没有找到就会到他的父级作用域中查找 , 如果父级也没找到就会接着一层一层的向上寻找,直到找到全局作用域还是没找到的话,就宣布放
弃。这种一层一层的作用域嵌套关系,就是 作用域链 。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值