js 变量提升和作用域的i理解


js 变量提升和作用域的理解

js 中的变量提升大体可以分为两种,一种是使用 var 声明的变量,另一种是函数的变量提升,而函数的创建可以分为函数声明和函数表达式两种,这两种具有不同的变量提升,以下为本人根据自己的理解参考其他博主的博客得出的看法,如有错误欢迎指正。

使用var声明的变量

我们首先先看一段代码,

function scopeTest(){
    console.log(test); // undefined
    var test = 'hello';
}
scopeTest();

以上代码输出的结果是 undefined,原因是 js 对于使用var声明的变量具有变量提升的特性,函数内部会首先声明函数内部需要的变量并赋值为undefined。以上代码等价于

function scopeTest(){
    var test;
    console.log(test);
    test = 'hello';
}
scopeTest();

没有使用var声明的会变成全局变量

var test = 'hello';
function scopeTest(){
    console.log(test) // hello
    test = 'helloworld';
}
scopeTest();
console.log(test); // helloworld

函数中的 test 变量没有使用var进行声明,所以并不具备变量提升,此时打印,打印的是上层作用域的test即 hello,由于 test 是直接声明的,那么 test 会成为全局变量,覆盖掉已经有的 test ,所以为函数执行完打印 test 输出的是 helloworld

函数提升

函数的创建分为两种,一种是使用function加函数名进行声明,另一中将函数赋值给变量

首先看第一种,声明方式如下

var a=1;
function foo(){
    console.log(a); //[Function: a]
    a=10;
    return;
    function a(){ }
}
foo();
console.log(a); // 1

这边我们可以看到最后打印的出的 a 是 1 而不是函数里赋值的10,原因是函数具有变量提升的特性,以上代码等价于

var a=1;
function foo(){
    function a(){ }
    console.log(a); //[Function: a]
    a=10;
    return;
}
foo();
console.log(a); // 1

函数内部首先声明 function a 此时函数内部的 a 为function类型,此时打印 a 可以看出是一个function 接下来 a = 10 将 a 的类型转为 number 并赋值为 10;然后return 函数销毁,函数内部的 a 变量被回收。最后打印的 a 还是全局的 a

上面是使用 function 进行申明的,下面试一下使用函数表达式的方式进行声明

var a=1;
function foo(){
    console.log(a); //undefined
    a=10;
    return;
    var a = function(){ }
}
foo();
console.log(a); // 1

这边可以看到第 3 行打印的是 undefined 而不是 function,同样具有变量提升但是两者却不一样,使用函数表达式的方式进行声明函数只会定义变量,函数体和函数内容并不会携带,但是使用function加函数名的方式会将函数名和函数体一起提升到函数的头部。
以上代码等价于

var a=1;
function foo(){
    var a;
    console.log(a); //undefined
    a=10;
    return;
    a = function(){ }
}
foo();
console.log(a); // 1

作用域

js 的作用域分为全局作用域和函数作用域,没有块级作用域,说起作用域就得说到作用域链。

var global='global context';
var inner='global inner context';
function foo(){
    console.log(global); 
    console.log(inner);
    var inner='inner context';
    console.log(inner);
}
foo();

第4行:foo 函数内部,首先打印global,由于函数内部没有这个变量,那么会从foo函数的外部作用域开始找这个变量,然后打印。
第5行:inner这个变量,由于变量提升,所有函数的头部存在inner变量的定义,打印出undefined
第7行:inner变量赋值,打印出 inner context

与作用域息息相关的是闭包,this指向问题。

感谢博主的文章
廖雪峰-变量作用域与解构赋值
深入javascript——作用域和闭包
js 变量提升和闭包理解

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值