ES6新特性之var、let、const详解

本文详细介绍了JavaScript ES6中的var、let、const的区别,重点在于它们的作用域行为。var具有变量提升且可跨块访问,let和const则在块级作用域内生效,let不允许重复声明,const则必须初始化并保持常量。此外,文章探讨了块级作用域带来的优点,如避免变量覆盖和循环变量泄露,以及函数声明的规则变化。最后,讨论了JavaScript对未声明变量赋值的处理机制。
摘要由CSDN通过智能技术生成

一、ES6新特性之var、let、const详解

作用域控制着变量和参数的可见性和生命周期。
JS中作用域有:全局作用域、函数作用域。没有块级作用域的概念。ECMAScript 6(简称ES6)中新增了块级作用域。
块级作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

var、let、const

  1. var定义的变量在全局范围内都有效,没有块的概念,可以跨块访问,不能跨函数访问。
    let定义的变量只在块级作用域内有效,不能跨块访问,也不能跨函数访问。
    const声明只读常量,只在块级作用域内有效,且声明时必须初始化(即必须赋值),后期值不可变,否则报错。
//var 
var a=1;
if(true){
	var b=2;
	for(i=0;i<1;i++){
		console.log(a);
		console.log(b);
	}
} 
var c=function(){
	var d=3;
}();
var e=function(){
console.log(d);//Uncaught ReferenceError: d is not defined
}();

//let
{
	let i1=1;
	console.log(i1);
	{
		let i2=1;
	}
	{
		console.log(i2);//Uncaught ReferenceError: i2 is not defined
		var fun1=function(){
			let i3=3;
		}();
		var fun2=function(){
			console.log(i3);//Uncaught ReferenceError: i3 is not defined
		}();
	}
}

2.var有变量提升, let、const都无变量提升

//若在定义一个变量之前使用该变量则会抛出ReferenceError错误,而var则会将变量视为undefined
console.log(p);//Uncaught ReferenceError: p is not defined
p=3;//Uncaught ReferenceError: Cannot access 'p' before initialization
let p;

console.log(r);//Uncaught ReferenceError: r is not defined
r=2;//Uncaught TypeError: Assignment to constant variable.
const r=1;

//下面看var 的变量提升
//例1:
console.log(q);//undefined (var声明的变量有变量提升,在js的预处理阶段,将var q;声明提升到最前面,此时暂时还未赋值,所以打印出来的结果为undefined )
var q=2;

//例2:
s=1;
console.log(s);
var s=2;
  1. var可重复声明同一变量,let、const都不可重复声明同一变量
var c=2;
var c=3;
console.log(c);//3

let b;
let b;//Uncaught SyntaxError: Identifier 'b' has already been declared

const a=1;
const a=1;//Uncaught SyntaxError: Identifier 'a' has already been declared
  1. 对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变
const a=[];
a.push('javascript');
console.log(a);//['javascript']
a=['java'];//Uncaught TypeError: Assignment to constant variable.

补充一、块级作用域

ES6的 let命令和const命令引入了的块级作用域的概念,块级作用域的优点:

  1. 避免内层变量覆盖外层变量
  2. 避免用来计数的循环变量泄露为全局变量
  3. 允许在块级作用域之中声明函数

ES5规定,函数只能在顶层作用域和函数作用域之外声明,不能在块级作用域中声明

if(true){
function func(){}
}
try{
function func(){}
}catch{
}
//上面两种函数声明在es5中都是非法的,但是浏览器没有遵守这一规定,还是支持在块级作用域中声明函数,因此以上两种情况实际都能运行,不会报错;但是在严格模式下,还是会报错;
'use strict'
if(true){
function func(){}//报错
} 

//ES6引入了块级作用域,明确允许在块级作用域中声明函数
'use strict'
if(true){
function func(){}//不报错
} 
//ES6还规定,在块级作用域中,函数声明的行为类似于let,在块级作用域之外不可引用;
//函数声明会提升到函数作用域头部;

//注意ES6的块级作用域允许函数只在使用大括号的情况下成立,如果未使用大括号,会报错
'use strict'
if(true){
function func1(){}//不报错
}
if(true)
function func2(){}//不报错
  1. ES6允许块级作用域的任意嵌套,外层作用域无法读取内层作用域的变量
{{{{{
{let i=1;}
console.log(i);//Uncaught ReferenceError: i is not defined
}}}}}
  1. 内层作用域可以定义外层作用域的同名变量,而不受影响
  2. 使立即执行函数不再需要,精简代码(直接用块级作用域{}代替)
//立即执行函数
(function(){
    var i=5;
})();
//块级作用域
{
let i=5;
}

补充二、JavaScript为什么对没有声明的变量赋值不会报错?

1.L/R查询

L就是左侧,R就是右侧。
来看var a = 2,js引擎会对a进行LHS(赋值操作的左侧)。另一个就是RHS(赋值操作右侧)

RHS查询就是简单的查找某个变量的值,找到还好,找不到就抛出异常
LHS查询则是试图找到变量的容器本身,从而可以对其进行赋值,找不到就会隐式的把它创建在全局作用域。

2.对于var a = 2,JavaScript引擎会在其作用域中对其进行编译,在这个过程中,会被分成两个步骤

1.首先,var a 在其作用域中声明新变量,这会在最开始阶段,也就是代码执行前
2.接下来,a = 2会查询(LHS)变量a,对其赋值
LHS和RHS都会在当前作用域中开始找,直到全局作用域中,无论找没找到都会停止
不成功的RHS会抛出异常(ReferenceError)
不成功的LHS会自动隐式地创建一个 全局变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值