资讯专栏INFORMATION COLUMN

es6 - 块级作用域

wuaiqiu / 1542人阅读

摘要:和块级作用域在高程中,作者强调说没有块级作用域。然而,这种情况在中发生了改变,通过在代码块中使用引入了块级作用域的特性。在块级作用域内部使用声明的变量,在块作用域外部是不可见的。

let const和块级作用域

在js高程中,作者强调说js没有块级作用域。
然而,这种情况在es6中发生了改变,es6通过在代码块中使用let, const引入了块级作用域的特性。
下面是对此特性的介绍。

语法 es5作用域和变量提升

首先,在es5中,只有两种作用域,函数作用域和全局作用域。 所有的变量和函数声明都存在于这两种作用域中。

js在执行时,会首先将函数定义和变量声明提升到作用域的顶部,而初始化的代码留在原处,这就是变量提升。 这是js语言与其他语言不同的地方。

块级作用域与let const

块级作用域简单来说就是使用{}包裹的一段代码,函数,判断,循环,甚至多带带的一个{}都可以看作一个块级作用域。

在块级作用域内部使用let, const声明的变量,在块作用域外部是不可见的。

准确的说,使用const声明的应该是一个常量,它的值是不可变的,应该在声明时完成初始化。在后面对const声明的变量赋值会导致错误。

在同一个作用域中,使用let或const重复声明变量是不被允许的。比如:

var count = 30;
let count = 20; //这里无论顺序,无论let或const,都会报错。

//只有这种才不会报错
var count = 30;
var count = 20; //第二个var被忽略,count等于20

let, const声明的变量并不会变量提升。另在,在作用域中,使用二者声明的变量存在一个暂时性死区TDZ,即在声明语句前对变量的访问和使用都会引发引用错误。比如:

if(condition){
    console.log(typeof value);//会报错
    let value = "icode007"
}
循环中的块级绑定

js有一道经典的面试题,即在页面插入10个a标签,点击每个标签时显示相应的序号。或者是:

var arr = [];
for(var i =0; i<10; i++){
    arr.push(function(){console.log(i)});
}
arr[5]();

这道题经常用来说明变量的作用域和闭包的相关问题。因为所有的函数引用的都是同一个i,所以都显示10.
正确的代码是使用立即执行函数,利用闭包特性:

var arr = [];
for(var i=0; i<10; i++){
    (function(i){
        arr.push(function(){console.log(i);});
    })(i);
}
arr[5]();

通过闭包,每个函数调用的实际上是其独有的i。

然而,在es6,有个更好的方案,使用let。只需将第一段代码i声明中var换成let即可。

在for循环中,每次迭代let都会创建一个新的同名变量,并进行初始化,相当于上面使用立即执行函数的行为。在for-in循环和for-of循环中,同样如此。

注意事项

const声明的变量是不可变的,其实质是变量所引用的指针不能发生变化,但由于js动态语言的本质,当const声明一个对象时,对对象的改变是允许的。比如:

const obj = {name: "icode"};
obj.name ="thoms"; //不会发生错误
obj = {name: "thoms"} //发生错误

在for-in和for-of迭代中使用const与使用let的行为相同,前提是不再代码块中改变它的值,在for循环中,由于i++会改变变量的值,所以会报错。

在之前全局中使用var定义的变量会成为window对象的一个属性,而在全局中使用let, const定义的变量不会成为window对象的属性。

最佳实践

推荐的最佳实践是尽量使用let而不是使用var去定义变量,这能让我们代码更加的规范。

更加推荐的做法是一般使用const定义变量,只有在预期变量会发生改动时才使用let来定义。因为大部分变量定义后是无需发生变化的。这种方式能减少代码出错的几率。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107493.html

相关文章

  • ES6学习 第一章 let 和 const 命令

    摘要:外层作用域不报错正常输出块级作用域与函数声明规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。规定,块级作用域之中,函数声明语句的行为类似于,在块级作用域之外不可引用。同时,函数声明还会提升到所在的块级作用域的头部。 前言:最近开始看阮一峰老师的《ECMAScript 6 入门》(以下简称原...

    番茄西红柿 评论0 收藏2637
  • ES6学习摘要(01)(新人学习)

    摘要:入门一前言由于最近本人在学习,做一些笔记能够更好的熟悉,就趁此机会来写一篇关于的新人学习摘要吧。的作用域与命令相同只在声明所在的块级作用域内有效。块级作用域新增方式和实际上为新增了块级作用域。同时,函数声明还会提升到所在的块级作用域的头部。 ECMAScript6/ES6 入门 一、前言 由于最近本人在学习ES6,做一些笔记能够更好的熟悉,就趁此机会来写一篇关于ES6的新人学习摘要吧。...

    dmlllll 评论0 收藏0
  • es6学习之let和const命令

    摘要:和命令命令是在它所在的代码块有效,它属于块级作用域,新增。只有全局作用域和函数作用域。 let和const命令 let命令是在它所在的代码块有效,它属于块级作用域,es6新增。es5只有全局作用域和函数作用域。let命令存在暂时性死区(TDZ),即在申明前使用就会报错,不存在变量提升 console.log(a); // 报错 let a = 111; ==let不允许在相同作用域中,...

    DrizzleX 评论0 收藏0
  • ES5和ES6作用详解

    摘要:允许在块级作用域内声明函数。上面代码中,存在全局变量,但是块级作用域内又声明了一个局部变量,导致后者绑定这个块级作用域,所以在声明变量前,对赋值会报错。 ES5的作用域 变量起作用的范围,js中能创建作用域的只能是函数 { let a = 1; var b = 2; } console.log(a); // a is not defined console.log(b); //...

    Dr_Noooo 评论0 收藏0
  • ES6精解:let、const、块级作用

    摘要:命令新增了命令,跟类似,都是用来声明变量的不允许重复声明报错不存在变量提升报错正确写法为既要先定义,后面才能有这个值,否则会报错,如果改成会提示未定义,但是就直接报错了暂时性死区只要在块级作用域里面存在则它所声明的变量就绑定在这个块级作用域 let命令 ES6新增了let命令,跟var类似,都是用来声明变量的 1.不允许重复声明 { let a = 1; let a =...

    BWrong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<