命令与变量解构赋值

let和const命令

let命令

  1. 不存在变量提升
    在变量声明之前使用会报错
  2. 暂时性死区
    当代码块存在let或者const命令时,那么在该代码块中,这些命令声明的变量,凡是在声明之前使用都会报错.(不论父作用域中有没有声明同名变量)
  3. let不允许在相同的作用域内重复声明一个变量

块级作用域

  1. let为javascript新增了块级作用域
    ES6允许块级作用域的任意嵌套;块级作用域让广泛应用的立即执行函数表达式没必要存在
  2. 块级作用域于函数声明
    ES5规定函数只能在顶层作用域和函数作用域中声明,不能再块级作用域声明.但是浏览器没有遵守这个规定.ES6引进了块级作用域,明确允许块级作用域中可以声明函数;ES6规定,块级作用域中,函数声明语句的行为类似于let.
    但是,如果真的在ES6浏览器中,实现规则并不是这样;如果改变了块级作用域内声明的函数的处理规则,会对老代码产生很大影响.为了减轻因此产生的不兼容问题,ES6规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式:
    • 允许在块级作用域内声明函数
    • 函数声明类似于var,存在变量提升
    • 函数声明还会提升到所在块级作用域的头部
attention
ES6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错.(注意一些可以省略大括号的情况)

const命令

const声明一个只读的常量,不能改变常量的值.特性同let命令声明的变量.
const实际保证的并不是变量的值不得改动,而是变量指向的内存地址不得改动.对于复杂数据类型,保存的知识一个指针,const只能保证这个指针是固定的,至于指向的数据结构是不是可以改变的则完全不能控制.

顶层对象

在ES5中,顶层对象的属性与全局变量是等价的.
ES6中,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let,const,class命令声明的全局变量,不属于顶层对象的属性.
ES5的顶层对象在各种实现里面不统一.


解构赋值

数组的解构赋值

基本用法
模式匹配,如果两边模式相同,那些左边的变量就会被赋予对应的值.如果解构不成功,变量的值就等于undefined;另外一种不完全解构,及等号左边的模式只匹配一部分等号右边的数组,依然可以解构成功.
如果等号右边的值转化为对象之后不具备Iterator接口或者本身就不具备Iterator接口会报错.

  • 默认值
    解构赋值允许指定默认值
    ES6内部使用严格相等运算符,判断一个位置是否有值.所以只有当一个数组成员严格等于undefined,默认值才会生效.
let [x,y = 0] = [1,undefined] //x=1,y=0

如果默认值是一个表达式,那么这个表达式
是惰性求值的,即只有在用到的时候才会求值.

对象的解构赋值

对象的属性没有次序,变量必须与属性同名.如果没有对应的同名属性,导致取不到值,最后等于undefined.
真正赋值的是键值对等号的后边,而不是左边.左边是匹配的模式.
数组和对象解构赋值都可以用于嵌套结构的对象.如果嵌套结构的对象需要每一层都赋值的话,那么需用逗号隔开,层层解构:

const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};

let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}
  • 默认值
    默认值生效的条件是,对象的属性值严格等于undefined
    如果解构失败,变量的值等于 undefined

如果将一个已经声明的变量用于解构赋值,须注意避免JavaScript引擎将已声明的变量理解成为一个代码块,从而发生语法错误.(不将大括号写在行首即可避免)

字符串的解构赋值

字符串被转换成一个类似数组的对象,类似数组的对象都有一个length属性.

数值和布尔值的解构赋值

解构赋值时,如果等号右边的值不是对象或者数组,就先将其转化为对象,由于undefinednull无法转换为对象,所以对它们进行解构赋值都会报错.

圆括号问题

ES6的规则是,只要是有可能导致解构的歧义,就不得使用圆括号.
不能使用圆括号的情况:

  • 变量声明语句
  • 函数参数
  • 赋值语句的模式

可以使用圆括号的情况:

  • 赋值语句的非模式部分

用途

  1. 交换变量的值
let x = 1;
let y = 2;

[x, y] = [y, x];
  1. 从函数返回多个值
    函数如果需要返回多个值只能返回一个数组或者对象,用解构赋值可以轻松取出.
  2. 函数参数的定义
    可以方便的将一组参数与变量名对应起来
  3. 提取JSON数据
  4. 函数参数的默认值
  5. 遍历 map结构
    任何部署了Iterator接口的对象,都可以使用for...of循环遍历,获取键名和键值非常方便
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
  1. 输入模块的指定方法

你可能感兴趣的:(命令与变量解构赋值)