每天3分钟,重学ES6-ES12(二)var let const的选择

简介: 每天3分钟,重学ES6-ES12(二)var let const的选择

19c2e7a9bfbb7f5e8c7d744db995e29.png

每天3分钟,重学ES6-ES12文章汇总

前言

今天开始和大家一起系统的学习ES6+,每天3分钟,用一把斗地主的时间,重学ES6+,今天介绍的是var let 和const。

let/const基本使用

  • 在ES5中我们声明变量都是使用的var关键字,从ES6开始新增了两个关键字可以声明变量:let、const
  • let、const在其他编程语言中都是有的,所以也并不是新鲜的关键字;
  • 但是let、const确确实实给JavaScript带来一些不一样的东西;
  • let关键字:
  • 从直观的角度来说,let和var是没有太大的区别的,都是用于声明一个变量
  • const关键字:
  • const关键字是constant的单词的缩写,表示常量、衡量的意思;
  • 它表示保存的数据一旦被赋值,就不能被修改;
  • 但是如果赋值的是引用类型,那么可以通过引用找到对应的对象,修改对象的内容;
  • 注意:另外let、const不允许重复声明变量;

代码演示


var foo = "foo"
let bar = "bar"
// const constant(常量/衡量)
const name = "abc"
name = "cba"
// 注意事项一: const本质上是传递的值不可以修改
// 但是如果传递的是一个引用类型(内存地址), 可以通过引用找到对应的对象, 去修改对象内部的属性, 这个是可以的
const obj = {
  foo: "foo"
}
obj = {}
obj.foo = "aaa"
console.log(obj.foo)
// aaa
// 注意事项二: 通过let/const定义的变量名是不可以重复定义
var foo = "abc"
var foo = "cba"
let foo = "abc"
// SyntaxError: Identifier 'foo' has already been declared
let foo = "cba"
console.log(foo)

let/const作用域提升

作用域提升:

在声明变量的作用域中,如果这个变量可以在声明之前被访问,那么我们可以称之为作用域提升;

  • let、const和var的另一个重要区别是作用域提升:
  • 我们知道var声明的变量是会进行作用域提升的;
  • 但是如果我们使用let声明的变量,在声明之前访问会报错;
  • ECMA262对let和const的描述;
  • 这些变量会被创建在包含他们的词法环境被实例化时,但是是不可以访问它们的,直到词法绑定被求值;
  • let、const没有进行作用域提升,但是会在解析阶段被创建出来。

代码演示


console.log(foo)
var foo = "foo"
// Reference(引用)Error: Cannot access 'foo' before initialization(初始化)
// let/const他们是没有作用域提升
// foo被创建出来了, 但是不能被访问
// 作用域提升: 能提前被访问
console.log(foo)
let foo = "foo"

let const 与window的关系

  • 全局通过var来声明一个变量,事实上会在window上添加一个属性
  • 但是let、const是不会给window上添加任何属性的。

块级作用域

  • 之前,我们都知道,在ES5中,JavaScript只会形成两个作用域:全局作用域和函数作用域
  • var 没有块级作用域,ES5中放到一个代码中定义的变量,外面是可以访问的:
// ES5中没有块级作用域
// 块代码(block code)
 {
   // 声明一个变量
   var foo = "foo"
 }
 console.log(foo)
  • 在ES6中新增了块级作用域,并且通过let、const、function、class声明的标识符是具备块级作用域的限制的
  • 但是我们会发现函数拥有块级作用域,但是外面依然是可以访问的:
  • 这是因为引擎会对函数的声明进行特殊的处理,允许像var那样进行提升;
// ES6的代码块级作用域
// 对let/const/function/class声明的类型是有效
{
  let foo = "why"
  function demo() {
    console.log("demo function")
  }
  class Person {}
}
// console.log(foo) // foo is not defined
// 不同的浏览器有不同实现的(大部分浏览器为了兼容以前的代码, 让function是没有块级作用域)
// demo()
var p = new Person() // Person is not defined

其他块级作用域


如 if语句的代码就是块级作用域,switch语句的代码也是块级作用域,for语句的代码也是块级作用域

//if语句的代码就是块级作用域
if (true) {
   var foo = "foo"
   let bar = "bar"
}
console.log(foo)
console.log(bar)
//foo
//Uncaught ReferenceError: bar is not defined
// switch语句的代码也是块级作用域
var color = "red"
switch (color) {
  case "red":
    var foo = "foo"
    let bar = "bar"
}
console.log(foo)
console.log(bar)
// foo
// Uncaught ReferenceError: bar is not defined
// for语句的代码也是块级作用域
for (var i = 0; i < 3; i++) {
     console.log("Hello World" + i)
}
 console.log(i)
// 3
for (let i = 0; i < 3; i++) {
     console.log("Hello World" + i)
}
console.log(i)
// Uncaught ReferenceError: i is not defined

暂时性死区

  • 在ES6中,我们还有一个概念称之为暂时性死区:
  • 它表达的意思是在一个代码中,使用let、const声明的变量,在声明之前,变量都是不可以访问的;
  • 我们将这种现象称之为 temporal dead zone(暂时性死区,TDZ);

代码演示


var foo = 'foo'
if(true){
    console.log(foo)
    // Uncaught ReferenceError: Cannot access 'foo' before initialization
    let foo = 'bar'
}

var let const 的选择

  • 那么在开发中,我们到底应该选择使用哪一种方式来定义我们的变量呢?
  • 对于var的使用:
  • 我们需要明白一个事实,var所表现出来的特殊性:比如作用域提升、window全局对象、没有块级作用域等都是一些 历史遗留问题;
  • 其实是JavaScript在设计之初的一种语言缺陷;
  • 当然目前市场上也在利用这种缺陷出一系列的面试题,来考察大家对JavaScript语言本身以及底层的理解;
  • 但是在实际工作中,我们可以使用最新的规范来编写,也就是不再使用var来定义变量了;
  • 对于let、const:
  • 对于let和const来说,是目前开发中推荐使用的;
  • 我们会有限推荐使用const,这样可以保证数据的安全性不会被随意的篡改;
  • 只有当我们明确知道一个变量后续会需要被重新赋值时,这个时候再使用let;
  • 这种在很多其他语言里面也都是一种约定俗成的规范,尽量我们也遵守这种规范;


5f7960c7d6df9745728a755b4491963.png


相关文章
|
7月前
ES6中的var,let,const
ES6中的var,let,const
|
7月前
|
安全 JavaScript 前端开发
ES6 中 let 与 const命令
ES6 中 let 与 const命令
|
3月前
|
JavaScript 前端开发
ES6学习(1)let,const
ES6学习(1)let,const
|
7月前
|
索引
【ES6新语法】let、const、var的区别,你学会了面试官没话说
【ES6新语法】let、const、var的区别,你学会了面试官没话说
|
7月前
|
JavaScript IDE 开发工具
es6学习笔记(一)let、const
es6学习笔记(一)let、const
|
JavaScript 前端开发 安全
ES6(let和const命令)
ES6(let和const命令)
88 0
|
JavaScript 前端开发
ES6——let、const
ES6——let、const
119 0
|
JavaScript 前端开发
【ES6】 let与const详解
【ES6】 let与const详解
|
JavaScript
ES6中let与const的区别
ES6中let与const的区别