ES6的变量声明详述

目录

1.var声明变量的问题

2.使用let声明变量

3.使用const声明变量


1.var声明变量的问题

(1)允许重复的变量声明:导致数据被覆盖

var a = 1;
function print() {
    console.log(a);
}
print();
var a = 2;
print();

(2)变量提升:怪异数据访问、闭包问题

怪异数据访问:即变量提升导致块级作用域内的变量可以在外部访问到

if (Math.random() < 0.5) {
    var a = "abc";
    console.log(a);
} else {
    console.log(a);
}
console.log(a);
图1-2

 闭包问题

var body = document.getElementsByTagName('body')[0];
for (var i = 1; i <= 10; i++) {
    var btn = document.createElement('button');
    btn.innerHTML = '按钮' + i;
    body.appendChild(btn);
    btn.onclick = function () {
        console.log(i);
    }
}

(3)全局变量挂载到全局对象,全局对象成员污染问题

console.log(window.name);
var name = 'abc';
console.log(window.name);
图1-3

 

2.使用let声明变量

(1)let声明的变量不会挂载到全局对象

let a = 123;
console.log(window.a);
图2-1

(2)let不允许在当前作用域内重复声明,在块级作用域中用let声明的变量在作用域外不能访问

【例】重复声明变量会报错

let a = 123;
let a = 456;
图2-2-1

 【例】作用域外访问块级作用域的变量会报错

{
    let a = 123;
}
console.log(a);
图2-2-2

 

(3)使用let不会有变量提升,因此不能再let定义变量之前使用该变量

【例】在变量声明前去访问该变量会报错

console.log(a);
let a = 123;
图2-2-3

 

【注】该错误提示为:不能在a初始化之前访问,而不是a未被定义,可见在底层实现上,let声明的变量实际上是提升了,拓展如下

(1)底层实现上,let声明的变量实际上也会有提升,但是提升后会将其放到“暂时性死区”,如果访问的变量位于暂时性死区,则报错如图2-2-3,当代码运行到该变量的声明语句时,会将其从暂时性死区中移出

(2)在循环中,用let声明的循环变量会被特殊处理,每次进入循环体都会开启一个新的作用域,并且将循环变量绑定到该作用域,则每次循环使用的是一个全新的循环变量

(3)在循环中,使用let声明的循环变量在循环结束后会销毁

【例】解决闭包问题

let body = document.getElementsByTagName('body')[0];
for (let i = 1; i <= 10; i++) {
    let btn = document.createElement('button');
    btn.innerHTML = "按钮" + i;
    body.appendChild(btn);
    btn.onclick = function () {
        console.log(i);
    }
}

3.使用const声明变量

const和let基本相同,区别在于用const声明的变量,必须在声明时赋值,而且不可以重新赋值

【例】在声明时未赋值,报错

const a;
a = 1;
console.log(a);
图3-1

【注】该报错信息为:在变量声明时没有初始化

【例】修改const声明的变量,报错

const a = 1;
a = 2;
console.log(a);
图3-2

实际上,在开发中应该尽量使用const来声明变量,以保证变量的值不会随意篡改,原因如下:

  • 根据经验,开发中的很多变量,都是不会更改的,也不应该更改
  • 后续的很多框架或者第三方JS库,都要求数据不可变,使用常量可以一定程度上保证这一点

【注】

(1)常量不可变,是指声明的常量的内存空间不可变,并不保证内存空间中的地址指向的其他空间不可变【例】

const a = {
    name: 'jwh',
    age: 18
};
a.name = 'zdw'
console.log(a);

【结果】

图3-3

 (2)常量的命名

  • 特殊的常量:该常量从字面意义上,一定是不可变的,比如圆周率、月地距离或者其他一些绝不可能变化的配置。通常,这些常量的名称全部使用大写,多个单词之间用下划线分割
  • 普通的常量:命名规则与之前相同

(3)在for循环中,循环变量不可以使用常量【例】

var arr = [{name:'jwh'},{age: 18}]
for (const i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

【结果】

图3-4

 

【例】forin循环可以用const声明变量

var obj = {
    name: 'jwh',
    age: 18
}
for(const prop in obj) {
    console.log(obj[prop]);
}

【结果】

图3-5

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值