详解var、let、const的特性及其区别

一. let命令

基本用法:跟使用es5的var一样,但有以下不同之处:

1. 不存在变量提升

var会存在变量提升现象,

letconst则不会有这种情况

2. 暂时性死区(TDZ)

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

3. 不允许重复申明

let不允许在相同作用域内,重复声明同一个变量。

// 报错
function func() {
  let a = 10;
  var a = 1;
}

// 报错
function func() {
  let a = 10;
  let a = 1;
}

因此,不能在函数内部重新声明形参。

function func(arg) {
  let arg; // 报错
}

function func(arg) {
  {
    let arg; // 不报错
  }
}

4. 块级作用域

为什么需要块作用域

ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

第一种场景,内层变量可能会覆盖外层变量。

var tmp = 123;

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

第二种场景,用来计数的循环变量泄露为全局变量。

var s = 'hello';
for (var i = 0; i < s.length; i++) {  
  console.log(s[i]);
}
console.log(i); // 5

ES6 的块级作用域

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

ES6 允许块级作用域的任意嵌套。

块级作用域的出现,实际上使获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

// IIFE 写法
(function () {
  var tmp = ...;
  ...
}());

// 块级作用域写法
{
  let tmp = ...;
  ...
}

块级作用域不返回值,除非tmp是全局变量,在外部可访问。

5. let声明的全局变量不再挂载到顶层对象,不再是顶层对象的属性

var a = 1;
let b = 2;
console.log(window.a); //a
console.log(window.b); //undefined

二. const

const声明一个只读的常量。

const除了以下两点与let不同外,其他特性均与let相同:

1. const一旦声明变量,就必须立即初始化,不能留到以后赋值。

2. 一旦声明,常量的值就不能改变。

本质

const限定的是赋值行为。

也就是说

const a = 1;
a = 2; //报错

// --------------------------------

const arr = [];
arr.push(1) //[1] 
//在声明引用型数据为常量时,const保存的是变量的指针,只要保证指针不变就不会报错。
//下面的行为就会报错
arr = [];  //报错 因为是赋值行为。变量arr保存的指针改变了。

三. 顶层对象属性与全局变量

顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。

window.a = 1;
a // 1

a = 2;
window.a // 2

顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。

为了解决这个问题,es6引入的letconstclass声明的全局变量不再属于顶层对象的属性。

而同时为了向下兼容,var和function声明的变量依然属于全局对象的属性

var a = 1;
window.a // 1

let b = 1;
window.b // undefined

四. 严格模式

严格模式是ES5引入的

严格模式主要有以下限制:

  1. 变量必须声明后再使用
  2. 函数的参数不能有同名属性,否则报错
  3. 不能使用with语句
  4. 不能对只读属性赋值,否则报错
  5. 不能使用前缀0表示八进制数,否则报错
  6. 不能删除不可删除的属性,否则报错
  7. 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
  8. eval不会在它的外层作用域引入变量
  9. eval和arguments不能被重新赋值
  10. arguments不会自动反映函数参数的变化
  11. 不能使用arguments.callee
  12. 不能使用arguments.caller
  13. 禁止this指向全局对象
  14. 不能使用fn.caller和fn.arguments获取函数调用的堆栈
  15. 增加了保留字(比如protected、static和interface)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值