ES6(持续更新中。。。)

let命令

  1. var命令全局有效,let命令只在块级作用域内有效
  2. let命令在for循环中,设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域
  3. let命令不存在变量提升,必须声明后使用
  4. let命令存在暂时性死区(TDZ),即只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不受外部影响。const命令如是。
  5. let命令不允许在相同作用域内重复声明同一个变量,所以不能在函数内部重新声明参数,因为参数和函数内部在同一个作用域里,当然在函数内部嵌套一个作用域再重新声明参数是被允许的

块级作用域

es5的缺点
  1. es5只有全局作用域和函数作用域,es6新增了一个块级作用域
  2. es5中全局作用域中变量声明提升,函数声明提升,逐行执行代码直到函数被调用后才执行函数作用域,函数作用域中依旧是变量声明提升,函数声明提升,逐行执行代码的步骤,这就导致了一种不好的现象,内部变量可能会覆盖外层变量。因为var命令是全局有效的,函数作用域变量声明提升的时候能会覆盖全局作用域里的变量。
  3. 同样地由于var命令全局有效的特性,也引发了另一种现象,就是循环变量泄露成为全局变量。for循环结束后,变量i的值指向的是全局,所以并没有消失,而是存在于全局作用域中。
块级作用域的优点
  1. 块级作用域中,外层代码块不受内层代码块的影响
  2. 块级作用域可以任意嵌套
  3. 块级作用域中,内层作用域可以定义外层作用域的同名变量
  4. 块级作用域的出现使得立即执行函数不再必要了,因为闭包产生的原因是内部函数(闭包函数)可以访问外部函数作用域,而块级作用域限制了这一功能。
块级作用域的特点
  1. 块级作用域中可以声明函数,但函数在块级作用域之外不可引用
  2. 块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
  3. 严格模式下,函数只能声明在当前作用域的顶层

const命令

  1. const声明一个只读的常量。一旦声明,常量的值就不能改变。
  2. 对于const来说,只声明不赋值,就会报错。
  3. const的作用域与let命令相同:只在声明所在的块级作用域内有效。
  4. const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
  5. const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
  6. 对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。
  7. ES6 声明变量的六种方法
  • var命令
  • function命令
  • let命令
  • const命令
  • import命令
  • class命令

顶层对象的属性

  1. 定义:顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。
  2. 顶层对象的属性与全局变量挂钩
  3. ES6中,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

globalThis对象

  1. 浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
  2. 浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
  3. Node 里面,顶层对象是global,但其他环境都不支持。
  4. 同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用this变量,但是有局限性。
  • 全局环境中,this会返回顶层对象。但是,Node 模块和 ES6 模块中,this返回的是当前模块。
  • 函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回undefined。
  • 不管是严格模式,还是普通模式,new Function(‘return this’)(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么eval、new Function这些方法都可能无法使用。
  1. 在语言标准的层面,引入globalThis作为顶层对象。也就是说,任何环境下,globalThis都是存在的,都可以从它拿到顶层对象,指向全局环境下的this。
  2. 垫片库global-this模拟了这个提案,可以在所有环境拿到globalThis。

数组的解构赋值

  1. ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

  2. ES6 允许写成:let [a, b, c] = [1, 2, 3];

  3. 可以从数组中提取值,按照对应位置,对变量赋值。

  4. 本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值:let [foo, [[bar], baz]] = [1, [[2], 3]];shuzu

  5. 如果解构不成功,变量的值就等于undefined。

  6. 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

  7. 如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。

  8. 对于 Set 结构,也可以使用数组的解构赋值。set

  9. 事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。fibs
    上面代码中,fibs是一个 Generator 函数,原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。

  10. 解构赋值允许指定默认值。

  11. 使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

  12. 如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

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

  14. 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

对象的解构赋值

  1. 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
  2. 如果解构失败,变量的值等于undefined。
  3. 对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
  4. 对象的解构赋值是右边形式的简写:let { foo, bar } = { foo: ‘aaa’, bar: ‘bbb’ };let { foo: foo, bar: bar } = { foo: ‘aaa’, bar: ‘bbb’ }; 的简写
  5. 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
  6. 与数组一样,解构也可以用于嵌套结构的对象。
  7. 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
  8. 对象的解构赋值可以取到继承的属性。
  9. 对象的解构也可以指定默认值。
  10. 默认值生效的条件是,对象的属性值严格等于undefined。
  11. 如果要将一个已经声明的变量用于解构赋值,必须非常小心。因为JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。例:
  • let x;({x} = {x: 1});
  1. 解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。例:
  • ({} = [true, false]);
  • ({} = ‘abc’);
  • ({} = []);
  1. 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。例:
  • let arr = [1, 2, 3];let {0 : first, [arr.length - 1] : last} = arr;

字符串的解构赋值

  1. 字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
  2. 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

数值和布尔值的解构赋值

  1. 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
  2. 解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

函数参数的解构赋值

  1. 函数的参数也可以使用解构赋值。
  2. 函数参数的解构也可以使用默认值。
  3. undefined就会触发函数参数的默认值。

圆括号问题

  1. 只要有可能导致解构的歧义,就不得使用圆括号。
  2. 建议只要有可能,就不要在模式中放置圆括号。
  3. 以下三种解构赋值不得使用圆括号。
  • 变量声明语句
  • 函数参数
  • 赋值语句的模式
  1. 可以使用圆括号的情况
  • 赋值语句的非模式部分,可以使用圆括号。
    • [(b)] = [3];
    • { p: (d) } = {});
    • [(parseInt.prop)] = [3];

变量的解构赋值用途

  1. 交换变量的值
    • let x = 1;let y = 2;[x, y] = [y, x];
  2. 从函数返回多个值
  3. 函数参数的定义
  4. 提取 JSON 数据
  5. 函数参数的默认值
  6. 遍历 Map 结构
  7. 输入模块的指定方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值