JS作用域,变量提升,作用域链,词法环境

变量作用域

JS有函数作用域,但是没有块作用域的概念。

值得注意的是,显示声明在函数里头的变量他是局部变量,若在函数里头直接使用未声明的变量则会隐式的声明成全局变量。

代码演示:

{
    var a = '其实我是全局作用域变量a';
    var b = '其实我是全局作用域变量b';
}
console.log(a);
(function fun(){
    var b = '局部作用域b';
    c = "其实我是全局作用域c"
    console.log(a);
    console.log(b);
    return fun;
})()

console.log(c);

运行结果:
在这里插入图片描述
注意:

  • JS没有块作用域;
  • 没有显示声明在函数里头的变量会被隐式声明全局变量。

ES(2015)6 const和let

在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量;
现在有了ES6的const和let,用该关键字在语句块进行声明的变量则作用域范围只在该语句块内可见。
代码演示:

{
    const a = "const";
    let b = "let";
    console.log(a);
}

console.log(a);

运行结果:
在这里插入图片描述
const定义常量与使用let 定义的变量相似。二者都是块级作用域

  • const
    const声明的变量必须进行初始化,const声明的变量不允许被重新赋值。
  • let
    let声明的变量可以不进行初始化,也可以进行重新赋值。

变量提升(hoisting)

变量没有被声明之前,也可以使用。

scope = "global"
var scope
console.log(scope)

//输出结果:global

变量提升只是对变量的声明提前了,而赋值并没有被提前。

console.log(scope)
var scope = "global"

//输出结果:undefined

非函数变量的提升比较容易明白,函数里的变量提升,你注意过?

var scope = "global"
function f(){
    console.log(scope);
    var scope = "local";
    console.log(scope)
}
f()

函数里的变量提升会将该变量声明提升到函数体的顶部,同时因为函数声明了该变量,那他就会取函数里的局部变量scope而不去打全局变量scope的注意了,但是因为提升的只是声明而不是初始化,所以输出undefined。
在这里插入图片描述
其实相当于这种情况了:

var scope = "global"
function f(){
    var scope
    console.log(scope);
    scope= "local";
    console.log(scope)
}
f()

作用域链

首先得明白,JavaScript是基于词法作用域的语言;怎么来理解这句话呢?
通俗来说,JS代码书写的时候就决定了作用域链,而不是取决运行的位置。

例如下面的案例:
fun1一开始是放在外头的,fun1输出的num的应该是全局作用域上的num。
首先在fun1函数作用域去找,没有就去全局变量去找,因为全局作用域没有定义num所以抛出ReferenceError异常;
尽管fun1是运行在fun2里面的,也尽管fun2作用域里有定义num;他认的还是fun1定义时候的作用域;

function fun1(){
    console.log(num)
}
function fun2 (){
    var num = "fun2"
    fun1()
}
fun2()

在这里插入图片描述
将fun1放到fun2里面取声明,则此时fun1没有num,则会去上一层作用域去寻找,上一层作用域是fun2作用域,所以输出的是fun2中的num

function fun2 (){
    var num = "fun2"
    function fun1(){
        console.log(num)
    }
    fun1()
}
fun2()

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaywei.online

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值