很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域。用var声明的变量具有变量提升(declaration hoisting)的效果。

ES6里增加了一个let,可以在{}, if, for里声明。用法同var,但作用域限定在块级,let声明的变量不存在变量提升。

示例1: 块级作用域 if

function getVal(boo) {
	if (boo) {
		var val = 'red'
		// ...
		return val
	} else {
		// 这里可以访问 val
		return null
	}
	// 这里也可以访问 val
}

变量val在if块里声明的,但在else块和if外都可以访问到val。

把var换成let,就变成这样了

function getVal(boo) {
	if (boo) {
		let val = 'red'
		// ...
		return val
	} else {
		// 这里访问不到 val
		return null
	}
	// 这里也访问不到 val
}

  

示例2: 块级作用域 for

function func(arr) {
	for (var i = 0; i < arr.length; i++) {
		// i ...
	}
	// 这里也可以访问到i
}

变量i在for块里声明的,但在for外也能访问到。

把var换成let,for外就访问不了i

function func(arr) {
	for (let i = 0; i < arr.length; i++) {
		// i ...
	}
	// 这里访问不到i
}

  

示例3: 变量提升(先使用后声明)

function func() {
	// val先使用后声明,不报错
	alert(val) // undefined
	var val;
}

变量val先使用后声明,输出undefined,也不报错。

把var换成let,就报错了

function func() {
	// val先使用后声明,报语法错
	alert(val)
	let val;
}

  

示例4: 变量提升(先判断后声明)

function func() {
	if (typeof val == 'undefined') {
		// ...
	}
	var val = ''
}

使用typeof判断时也可以再var语句的前面

但把var换成let,if处报语法错

function func() {
	if (typeof val == 'undefined') {
		// ...
	}
	let val = '';
}

ES6规定,如果代码块中存在let,这个区块从一开始就形成了封闭作用域。凡是在声明之前就使用,就会报错。即在代码块内,在let声明之前使用变量都是不可用的。语法上有个术语叫“暂时性死区”(temporal dead zone),简称TDZ。当然TDZ并没有出现在ES规范里,它只是用来形象的描述。

let的注意事项

1. 不能重复声明

// var和let重复声明
var name = 'Jack';
let  name = 'John';

// 两个let重复声明
let age = 24;
let age = 30;

执行时报语法错

2. 有了let后,匿名函数自执行就可以去掉了

// 匿名函数写法
(function () {
  var jQuery = function() {};
  // ...
  window.$ = jQuery
})();

// 块级作用域写法
{
  let jQuery = function() {};
  // ...
  window.$ = jQuery;
}

  

相关:

变量的6个属性

ES6块级作用域及新变量声明(let)的更多相关文章

  1. ES6块级作用域

    块级作用域的优点 避免变量冲突,比如程序中加载了多个第三方库的时候,如果没有妥善地将内部私有函数或变量隐藏起来,就很容易引发变量冲突: 可以方便的进行模块管理: 利于内存回收:(块级作用域里声明的变量 ...

  2. ES6——块级作用域

    前面的话 过去,javascript缺乏块级作用域,var声明时的声明提升.属性变量等行为让人困惑.ES6的新语法可以帮助我们更好地控制作用域.本文将详细介绍ES6新引入的块级作用域绑定机制.let和 ...

  3. ES6 块级作用域

    作用域包括:全局作用域,函数作用域,块级作用域. 为什么要用块级作用域: 1.内层变量可能会覆盖外层变量. var name = "kevin"; function call() ...

  4. JavaScript函数表达式、闭包、模仿块级作用域、私有变量

    函数表达式是一种非常有用的技术,使用函数表达式可以无需对函数命名,从而实现动态编程.匿名函数,是一种强大的方式,一下总结了函数表达式的特点: 1.函数表达式不同于函数声明,函数声明要求有名字,但函数表 ...

  5. javascript中不存在块级作用域,所以要小心使用在块级作用域中的函数声明所带来的作用域混乱.

    在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...

  6. ES6的 let const 以及块级作用域

    let声明变量 用法类似于var,但是所声明的变量只在let所在的代码块内有效. 1 . 在ES6环境下,let声明的变量不能在声明之前调用. 例: console.log(i); //会报错,这叫做 ...

  7. ES6之块级作用域

    一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1.  全局作用域: 2.  函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...

  8. ECMAScript 6学习笔记(二):let和块级作用域

    同步发布于:https://mingjiezhang.github.io/(转载请说明此出处). ES6中加入了let,也让JavaScript拥有了块级作用域. 没有块级作用域的JavaScript ...

  9. 你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域

      原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到 ...

随机推荐

  1. touches 事件捕获不到

    在UIView上加载了一个UIScrollView(全屏),touches 事件捕获不到了 原因:UIView的touch事件被UIScrollView捕获了,无法传递下去 解决方法:写一个UIScr ...

  2. go智能提示(重要)

    使用VIM开发go程序时,智能提示是一个大问题. 最终解决方案是使用 YCM,它是使用 gocode 来进行智能提示的.一切配置好之后,你会发现标准库和第三方库都可以智能提示,但自己写的包却不能,猜想 ...

  3. Struts2之OGNL

    一.OGNL是什么? OGNL(Object-Graph Navigation Language)对象图导航语言,是一种表达式语言,它可以 1.遍历对象的结构图 2.存取对象的属性(实例属性和静态属性 ...

  4. Scrum敏捷软件开发之技术实践——测试驱动开发TDD

    重复无聊的定义 测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法.它要求在编写某个功能的代码之前先编写测试代码,然后只编写 ...

  5. [你必须知道的.NET]第三十五回,判断dll是debug还是release,这是个问题

    发布日期:2009.12.29 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 问题的提出 晚上翻着群里的聊天,发现一个有趣的问题:如何通过编码 ...

  6. Android Layout_Gravity和Gravity

    简单来说layout_gravity表示子控件在父容器的位置,gravity表示控件内容在控件内的位置. 上面图片的xml代码 <?xml version="1.0" enc ...

  7. LWIP互联网资料汇总

    本文主要搜集了下互联网上关于LWIP的资料和教程 欢迎补充 第一部分:移植 LWIP在UCOS上移植 LWIP 在STM32上移植   http://www.docin.com/p-459242028 ...

  8. MSM平台RPM

    Software Component Block Diagram RPM(Resource Power Manager)是高通MSM平台另外加的一块芯片,虽然与AP芯片打包在一起,但其是一个独立的AR ...

  9. 11-Cookie&amp;Session

    中文文件下载 针对浏览器类型,对文件名字做编码处理 Firefox (Base64) , IE.Chrome ... 使用的是URLEncoder /* * 如果文件的名字带有中文,那么需要对这个文件 ...

  10. 西安OpenParty11月29日活动高清图文回顾——新增西安APEC蓝美图!

    本次活动由西安OpenParty负责线下活动组织运营,线上由InfoQ-QClub.OSChina协办. OSChina活动召集帖:运维为王——应用系统.DevOps与Docker(11月29日) I ...