ES6学习教程之块级作用域详解


Posted in Javascript onOctober 09, 2017

前言

众所周知ES5之前javascript语言只有函数作用域和全局作用域,使用var来声明变量,var声明的变量还存在变量提升使人困惑不已。我们先来复习一下ES5的var声明,再对比学习let和const 。

var

var声明之函数作用域和全局作用域。

来段代码体会一下:

function getName() {
 if (1 + 1 === 2) {
 var name = 'xixi';
 }

 console.log(name);
}

getName();//xixi

在c或java语言中name本应该只在if块中使用的,但是在if的外面也可以访问到,这个就是 js没有块级作用域的一种体现。这个弊端在for循环中体现的十分明显:

for (var i = 0; i < 10; i ++) {
 // ...
}

console.log(i);// 10

var i的本意是声明个临时变量i,用来遍历数组等,本不应该在for循环的外部访问到,但现在却可以被访问到你说闹不闹心?好一点的程序员会用立即执行函数来模拟块级作用域,原来的我会注意一下尽量不使用相同的变量名?。

(function() {
 for (var i = 0; i < 10; i ++) {
 // ...
 }
})();

console.log(i);// undefined

以上:大家知道了 js 没有块级作用域。

变量可以重复声明

var name = 'xixi';
console.log(name);// xixi
var name= '一步';
console.log(name);// 一步

不报错,困惑不困惑,这个就是变量可以重复声明。

变量提升

function getName() {
 console.log(name);
 var name = 'xixi';
 // ...
}

getName();// undefined

console.log打印name为undefined。为啥不报错呢,对于一直使用js语言的人来说这个现象还好理解,如果是后台转前端的人来说估计得骂人了。这就是所谓的变量提升。简单的向大家解释一下吧。

var name = 'xixi';

这是一条被我们写烂了的语句,包含两个过程:var name; name = 'xixi';分别为变量声明和变量初始化。

变量提升: 无论变量声明var name;处于什么位置,都会被提到作用域的顶部进行。

let

ES6为让变量生命周期更加可控,引入两个非常好的特性let、const。块级作用域、不能重复声明、临时性死区等特性用来解决 var 变量存在的种种问题。

块级作用域

function getName4ES6() {
 if (1 + 1 === 2) {
 let name = 'xixi';
 }

 console.log(name);
}

getName4ES6(); // undefined

终于在{}外面访问不到name了。for循环也变的简单了,大家试一下将for循环的var换成 let.

同一块级作用域内不能重复声明变量

function redefineValue() {
 let name = 'xixi';
 let name = '一步';
}

redefineValue();// Uncaught SyntaxError: Identifier 'name' has already been declared

重复声明会报错

{
 let name = 'xixi';
 console.log(name);// xixi
 {
 let name = 'yibu';
 console.log(name); // yibu
 }
}

注意: 在 ES6中,{}就是一个块级作用域。

临时性死区

function getName4ES6() {
 console.log(name);
 for (let i = 0; i < 10; i ++) {

 }
 let name = 'xixi';
 // ...
}

 
getName4ES6();// Uncaught ReferenceError: name is not defined

在上文ES5中,name还会存在变量提升,值为undefined。ES6中又报错了。怎么解释呢?。。。。这个就是临时性死区的概念,在作用域块中不可以在变量声明前就使用变量,若使用是会出错的。

javascript引擎在发现变量声明时,要么将变量声明提升到作用域的顶部(var声明变量时),要么将变量放在临时性死区中(let、const声明变量时),访问临时性死区中的变量会触发运行时错误。

ES6学习教程之块级作用域详解

const

const和let同样具有块级作用域,不能重复声明,临时性死区的概念。它还具有两个特有的特性:声明的同时必须初始化、变量引用不可以改变。

声明的同时必须初始化

const name;//Uncaught SyntaxError: Missing initializer in const declaration

不赋值,就报错。这个也很好理解const的本意就是用来定义常量,不可变的值。若不在声明时给出初始值以后就再也没有机会了。

值不可变

const name = 'x9x9';
name = 'yyy';// Uncaught SyntaxError: Invalid or unexpected token

那么对象会怎样呢?

const person = {
 name: 'lala',
 age: 40
};

person = {};// VM1042:6 Uncaught TypeError: Assignment to constant variable. at <anonymous>:6:8

引用是不可变的,那我们在看看对象的属性值是什么情况吧~

person.name = 'yoyo';
console.log(person);// {name: "yoyo", age: 40}

没有报错,对象引用不可改变,对象属性可以变更。

let vs const

大家可能会困惑,什么时候使用let,什么时候使用const。let能做的const好像都可以。网上有一种流行做法:能用const就绝不用let,简单粗暴,不过很好用。

个人看法:若变量在后续方法中会被改变,就使用let。一些常量声明使用const, const声明的变量名全部大写。代码中的变量,如果是let声明的就代表其可变,若是const声明的,不论是简单数据类型还是引用类型变量就都不要改变它的值。这样,程序会更加的健壮,大家合作起来也比较方便。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
Mar 24 Javascript
js实现DOM走马灯特效的方法
Jan 21 Javascript
浅谈JavaScript的Polymer框架中的behaviors对象
Jul 29 Javascript
js实现网站最上边可关闭的浮动广告条代码
Sep 04 Javascript
node.js中 stream使用教程
Aug 28 Javascript
微信小程序-获得用户输入内容
Feb 13 Javascript
提高Node.js性能的应用技巧分享
Aug 10 Javascript
实例详解ztree在vue项目中使用并且带有搜索功能
Aug 24 Javascript
jQuery属性选择器用法实例分析
Jun 28 jQuery
js模拟F11页面全屏显示
Sep 17 Javascript
vue-next/runtime-core 源码阅读指南详解
Oct 25 Javascript
JavaScript canvas基于数组生成柱状图代码实例
Mar 06 Javascript
JavaScript实现短信倒计时60s
Oct 09 #Javascript
ES6学习教程之对象字面量详解
Oct 09 #Javascript
AngularJS中的路由使用及实现代码
Oct 09 #Javascript
React如何利用相对于根目录进行引用组件详解
Oct 09 #Javascript
React Native中的RefreshContorl下拉刷新使用
Oct 09 #Javascript
JS实现的全排列组合算法示例
Oct 09 #Javascript
js + css实现标签内容切换功能(实例讲解)
Oct 09 #Javascript
You might like
POSIX 风格和兼容 Perl 风格两种正则表达式主要函数的类比(preg_match, preg_replace, ereg, ereg_replace)
2010/10/12 PHP
第七章 php自定义函数实现代码
2011/12/30 PHP
PHP中数字检测is_numeric与ctype_digit的区别介绍
2012/10/04 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
Yii框架getter与setter方法功能与用法分析
2019/10/22 PHP
统计出现最多的字符次数的js代码
2010/12/03 Javascript
javascript 按键事件(兼容各浏览器)
2013/12/20 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
Mvc提交表单的四种方法全程详解
2016/08/10 Javascript
分享十三个最佳JavaScript数据网格库
2017/04/07 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
for循环 + setTimeout 结合一些示例(前端面试题)
2017/08/30 Javascript
基于Vue生产环境部署详解
2017/09/15 Javascript
JS实现读取xml内容并输出到div中的方法示例
2018/04/19 Javascript
vue+vue-router转场动画的实例代码
2018/09/01 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
[04:03]辉夜杯主赛事 12月25日RECAP精彩回顾
2015/12/26 DOTA
python函数局部变量用法实例分析
2015/08/04 Python
Python数据拟合与广义线性回归算法学习
2017/12/22 Python
Python实现的三层BP神经网络算法示例
2018/02/07 Python
Python cookbook(数据结构与算法)实现优先级队列的方法示例
2018/02/18 Python
python中的字符串内部换行方法
2018/07/19 Python
django+echart绘制曲线图的方法示例
2018/11/26 Python
代码实例讲解python3的编码问题
2019/07/08 Python
python单向循环链表原理与实现方法示例
2019/12/03 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
2020/04/23 Python
python报错: 'list' object has no attribute 'shape'的解决
2020/07/15 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
日本著名的平价时尚女性购物网站:Fifth
2016/08/24 全球购物
俄罗斯儿童和青少年服装、鞋子及配件的在线商店:Orby
2020/02/20 全球购物
大家访活动实施方案
2014/03/10 职场文书
2014年行政助理工作总结
2014/11/19 职场文书
社区植树节活动总结
2015/02/06 职场文书
婚宴父母致辞
2015/07/27 职场文书
python Django框架快速入门教程(后台管理)
2021/07/21 Python