ES6-let,块级作用域,const

let
let命令有四大主要特性:存在块级作用域,没有变量提升,暂时性死区,不允许重复声明

1、存在块级作用域

let命令声明的变量只在其块级作用域中有效,就是{}中。
{
let a = 10;
var b = 1;
}
console.log(a); //出错 not defined
console.log(b); //1
es5中要实现块级作用域,通常借助立即执行匿名函数来实现,如下::
(function(){
var a = 1;
}());
console.log(a); //出错,not defined
但是有了let之后,我们可以使用{}直接实现,如下:
{
let a = 1;
}
console.log(a); //出错, not defined
2、没有变量提升

我们在使用var进行变量定义时,会发生变量提升。即脚本开始运行时,变量a就已经存在,但是未被赋值,因此在赋值前输出时,则会输出undefined
console.log(a); //undefined
var a =1;

// 上述代码等价于
var a
console.log(a)
a = 1
而使用let命令,则改变了该语法行为。使用let声明的变量不存在变量提升,因此变量必须在声明后使用,否则会报错,如下:
console.log(a); //出错, not defined
let a = 1;
3、暂时性死区

在块级作用域内,若存在用let命令声明的变量,则所在区块对该变量形成封闭作用域,即该变量无视外部的同名变量。
而又因为不存在变量提升,因此在未使用let声明变量前,该变量都不可使用,其在语法上称为“暂时性死区”。

let a = 1;
if(true){
a = 2; //出错 not defined
let a;
}
对比var
var a = 1;
if(true){
a = 2; //var允许重复声明,而且变量提升,故a=2正常赋值var a;
}
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
4、不允许重复调用

let不可以在相同作用域内重复声明同一个变量,也包括不能和var,const变量名重复
{
let a = 1;
let a = 2;
} //出错 let不可重复声明

{
var b = 1;
let b = 1;
} //出错 let不可重复声明

function func(arg) {
let arg;
}
func() // 报错
块级作用域
1、为什么需要块级作用域?

在ES5中,只有全局作用域和函数作用域,不存在块级作用域,这就会导致如下问题的发生
1)内层变量覆盖外层变量
2)用于循环的计数变量会泄露为全局变量
如下所示:
// 没有块级作用域,内层变量会覆盖外层变量
var time = new Date()
function fun (){
console.log(time)
if(false){
var time = ‘hello world’
}
}
fun()

// 没有块级作用域,用来循环的计数变量会泄露为全局变量
var string = ‘hello world’
for(var i=0;i<string.length;i++){
console.log(string[i])
}
console.log(‘循环结束’)
console.log(i)
2、ES6的块级作用域

为了解决以上问题,ES6通过使用let为javascript 增加了块级作用域
function fun2 (){
let num = 100
if (true){
let num = 200
}
console.log(num)
}
fun2() // 100

for (let k=0;k<10;k++){
console.log(k)
}
console.log(‘循环结束’)
console.log(k) // ReferenceError: k is not defined
3、ES6中块级作用域允许其任意嵌套,外层作用域无法读取内层作用域的变量

{{{{
{let insane = ‘Hello World’}
console.log(insane); // 报错
}}}};
const
const 声明一个只读的常量。一旦声明,常量的值就不能改变。正是因为其值不能进行修改,因此, ,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
const与let一样, 只在声明所在的块级作用域内有效
const命令声明的常量不存在提升
const命令声明的常量同样存在暂时性死区,只能在声明的位置后面使用。
const声明的常量,也与let一样不可重复声明
本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
- 简单数据类型( 数值、字符串、布尔值): 值就保存在变量指向的那个内存地址,因此等同于常量
- 复合数据类型( 对象和数组) : 变量指向的内存地址,保存的只是一个指向实际数据的指针 , const只能保证这个指针是固定的 至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
const arr = []
arr.push(‘hello wrold’) // 可执行
arr.length = 0 // 可执行
arr = [‘hello everyone’] // arr is read-only

const person = {}
person.name = ‘zhangsan’ // 可执行
console.log(person.name) // zhangsan
person = {} //person is read-only
对象冻结:如果希望将一个对象进行冻结,可使用Object.freeze(),如下所示:
const person = Object.freeze({})
person.age = 30
person.name = ‘zhangsan’
console.log(person.age) // undefined
console.log(person.name) // undefined
console.log(person)
但上面的冻结方式只是将其对象本身冻结,其对象的属性也应该冻结,我们可以使用如下函数:
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === ‘object’ ) {
constantize( obj[key] );
}
});
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值