ES6知识点总结

let 和 const 命令

let 用来声明变量,只在let命令所在的代码块中有效。【代码块:使用花括号包住的内容称为代码块{}】

{
  let a = 10;
  var b = 1;
}
a //  ReferenceError: a is not defined
b // 1

表明:let声明的变量只在它所在的代码块有效。

for循环的计数器,就很合适使用let命令。

for (let i = 0; i < 10; i++) {
  // ...
}

console.log(i);
// ReferenceError: i is not defined

上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。

下面的代码如果使用var,最后输出的是10。

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。

for循环设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

代码正确运行,输出了 3 次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。

let 不存在变量提升

var命令会发生“变量提升”现象,变量可以在声明之前使用,值为undefined。

为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

// var 的情况

console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

let命令声明的bar,不会发生变量提升。在声明它之前,变量bar是不存在的。

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

var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError: tmp is not defined
  let tmp;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

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

总结, 在代码块内,使用let命令声明变量之前,该变量都是不可用的 这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

不允许重复声明

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


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


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

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

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

const 命令

1.基本规则

声明只读常量
声明后不可修改
一旦声明必须赋值,不赋值,会报错。
const的作用域只在声明的块级域内有效。
声明的常量不提升,存在暂时性死区,只能在声明的位置后面使用
const声明的常量,与let一样不可重复声明(不管使用var、let、还是const声明均不可)
2.本质
并不是值不可变动,而是变量指向的内存地址所保存的数据不得改动
对于简单类型的数据(数值、字符串、布尔值),值保存在变量所指向的内存地址,因此等同于变量。
对于复合类型的数据(对象与数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证指针是固定的,即总指向另一个固定的地址,并不能控制其地址中所存的数据。所以将对象声明为常量时需要小心。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

为什么出现块级作用域
内层变量可能覆盖外层变量

var a = new Date();
function fn(){
console.log(a);
if(false){
var a = “hello”;
}
}
fn(); // undefined

用来计数的循环变量泄露为全局变量

var s = "hello";
for (var i = 0; i < s.length; i++) {
    console.log(s[i]); // h e l l o
}
console.log(i); // 5

变量i只用来控制循环,但是循环结束之后,i变量并没有消失,而是泄露成了全局变量

顶层对象的属性

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

var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1

let b = 1;
window.b // undefined

变量的解构赋值

目录结构:

一、什么是解构
二、解构数组

1、变量声明并赋值的解构
2、变量先声明后赋值的解构
3、默认值
4、交换变量
5、解析一个从函数返回的数组
6、将剩余数组赋值给一个变量
7、for循环解构

三、解构对象
1、基本赋值
2、无声明赋值
3、给新的变量名赋值
4、默认值
5、给新的变量命名并提供默认值
6、对象传参解构
7、解构嵌套对象和数组
8、For of 迭代和解构

什么是解构:
解构是可以快速取得数组或对象当中的元素或属性,ES6中按一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构。(无需使用arr[x]或者obj[key]等传统方式进行赋值)。

以前,为变量赋值,只能直接指定值。

var a = 1;
var b = 2;

ES6允许写成下面这样。
var [a, b] = [1, 2];

上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

下面是一些使用嵌套数组进行解构的例子。

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

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

let [foo] = [];
let [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。

二、解构数组
1、 变量声明并赋值时的解构

var foo = ["one", "two", "three"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

2、变量先声明后赋值时的解构
通过解构分离变量的声明,可以为一个变量赋值。

var a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

3、默认值
为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值。

var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

4、交换变量
在一个解构表达式中可以交换两个变量的值。
没有解构赋值的情况下,交换两个变量需要一个临时变量(或者用低级语言中的XOR-swap技巧)。

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

5、解析一个从函数返回的数组
从一个函数返回一个数组是十分常见的情况。解构使得处理返回值为数组时更加方便。

在下面例子中,要让 [1, 2] 成为函数的 f() 的输出值,可以使用解构在一行内完成解析。

function f() {
  return [1, 2];
}

var a, b; 
[a, b] = f(); 
console.log(a); // 1
console.log(b); // 2

6、将剩余数组赋值给一个变量
当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。

var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

注意:如果剩余元素右侧有逗号,会抛出 SyntaxError,因为剩余元素必须是数组的最后一个元素

var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma

7、for循环解构

var arr = [[11, 12], [21, 22], [31, 32]];
for (let [a, b] of arr) {
    console.log(a);
    console.log(b);
}
//11
//12
//21
//22
//31
//32
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值