程序员书籍笔记 程序员书籍笔记
  • HTML
  • CSS
  • JavaScript
  • 前端知识
  • Vue
  • MarkDown
  • git
  • Node.js
  • Linux
  • 51单片机
  • 四级
  • 第一学期课程
  • 操作系统
  • 计算机网络
  • 数据结构
  • 计算机组成原理
  • HTML5
  • Electron
  • 日记便签
  • 前端导航
GitHub (opens new window)
  • HTML
  • CSS
  • JavaScript
  • 前端知识
  • Vue
  • MarkDown
  • git
  • Node.js
  • Linux
  • 51单片机
  • 四级
  • 第一学期课程
  • 操作系统
  • 计算机网络
  • 数据结构
  • 计算机组成原理
  • HTML5
  • Electron
  • 日记便签
  • 前端导航
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

    • es6

      • es6基础
        • 变量结构赋值
          • 数组解构赋值
          • 数组解构默认值
          • 对象解构赋值
          • 对象解构默认值
          • 其它类型的解构赋值
        • 圆括号问题
          • 不能使用的情况
          • 可以使用的情况
        • 解构用途示例
          • 交换变量的值
          • 从函数返回多个值
          • 函数参数的定义
          • 提取 json 数据
          • 函数参数的默认值
          • 遍历 Map 结构
      • es5的扩展
      • let和const命令
    • 基础
    • 运算符和数组
    • 函数
    • 对象和类型
    • 数据类型
    • js接口
    • DOM案例
    • 节点操作
    • BOM接口
    • 页面操作
    • 动画和轮播图
    • 本地存储
    • js面向对象
    • es6
    • ES6
    • js面向对象1
    • js面向对象2
    • js面向对象3
  • GO

  • 正则表达式

  • java

  • TypeScript

  • react

  • 前端知识

  • jQuery

  • Python

  • C和C++

  • 前端和后端
  • JavaScript
  • es6
yuadh
2022-05-02
目录

es6基础

# 变量结构赋值

# 数组解构赋值

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

let [a, b, c] = [1, 2, 3];
1

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

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

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 // []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

注意

如果结构不成功,变量的值会等于 undefined

在部分成功的清空下,解构依然可以成功

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

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
1
2
3
4
5
6
7
8

报错情况

如果解构的对象是不可遍历的解构

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
1
2
3
4
5
6

事实上,只要某种数据解构具有 iterator 接口,都可以采用数组形式的解构赋值

# 数组解构默认值

解构赋值允许指定默认值

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
1
2
3
4
5

ES6 内部使用严格相等运算符,判断一个位置是否有值.当一个值严格等于 undefined 时,默认值才会生效

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null
1
2
3
4
5

注意

默认值的表达式是惰性求值的,所有只有在没有值的情况下才会被执行

function f() {
  console.log('aaa');
}

let [x = f()] = [1]; //x 1
1
2
3
4
5

默认值还可以引用其它变量

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined
1
2
3
4

# 对象解构赋值

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
1
2
3

对象的解构与数组有一个重要的 不同 。数组的元素是按依次排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确值

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
1
2
3
4
5
6

方法的取值

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello
1
2
3
4
5
6

如果想要变量名与属性名不一致

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
1
2
3
4
5
6
7

这也是解构赋值的内部机制,先找到同名的属性,然后再赋给对应的变量。

真正赋值的是后者,而不是前者

注意

与数组一样,解构也可以用于嵌套结构的对象

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
1
2
3
4
5
6
7
8
9
10

注意,这时 P 是模式,不是变量不会被赋值

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
1
2
3
4
5
6
7
8
9
10
11

嵌套赋值

let obj = {};
let arr = [];

({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });

obj // {prop:123}
arr // [true]
1
2
3
4
5
6
7

注意

对象的结构赋值可以取到继承的属性

const obj1 = {};
const obj2 = { foo: 'bar' };
Object.setPrototypeOf(obj1, obj2);

const { foo } = obj1;
foo // "bar"
1
2
3
4
5
6

# 对象解构默认值

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

同样:默认值生效的条件是,对象的属性值严格等于 undefined

注意点

  1. 如果要将一个已经声明的变量用于解构赋值

    // 错误的写法
    let x;
    {x} = {x: 1};
    // SyntaxError: syntax error
    
    1
    2
    3
    4

    因为 {x} 会被引擎理解为代码块,解决这个问题需要使用 ()

    // 正确的写法
    let x;
    ({x} = {x: 1});
    
    1
    2
    3
  2. 解构赋值允许等号的左边不放置任何变量名

    ({} = [true, false]);
    ({} = 'abc');
    ({} = []);
    
    1
    2
    3

    虽然这些表达式毫无意义,但是没有语法错误

  3. 因为数组本质是特殊的对象,可以使用数组下标进行对象属性的解构赋值

    let arr = [1, 2, 3];
    let {0 : first, [arr.length - 1] : last} = arr;
    first // 1
    last // 3
    
    1
    2
    3
    4

# 其它类型的解构赋值

# 字符串

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
let {length : len} = 'hello';
len // 5
1
2
3
4
5
6
7
8

# 数值和布尔值

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true
1
2
3
4
5

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

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

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
1
2

# 函数参数

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3
1
2
3
4
5

const [x,y]=[1,2]

函数的参数的解构也可以使用默认值

function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
1
2
3
4
5
6
7
8

报错情况

function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
1
2
3
4
5
6
7
8

因为给参数传递了值,所有默认值惰性加载没有赋值 , 所以出现 undefined 情况

# 圆括号问题

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

# 不能使用的情况

赋值语句的模式部分

  1. 变量声明语句

    // 全部报错
    let [(a)] = [1];
    
    let {x: (c)} = {};
    let ({x: c}) = {};
    let {(x: c)} = {};
    let {(x): c} = {};
    
    let { o: ({ p: p }) } = { o: { p: 2 } };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  2. 函数的参数

    // 报错
    function f([(z)]) { return z; }
    // 报错
    function f([z,(x)]) { return x; }
    
    1
    2
    3
    4

    函数参数也属于变量声明,因此不能带有圆括号

  3. 赋值语句的模式

    // 全部报错
    ({ p: a }) = { p: 42 };
    ([a]) = [5];
    // 报错
    [({ p: a }), { x: c }] = [{}, {}];
    
    1
    2
    3
    4
    5

# 可以使用的情况

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
1
2
3

# 解构用途示例

# 交换变量的值

let x = 1;
let y = 2;

[x, y] = [y, x];
1
2
3
4

# 从函数返回多个值

// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 函数参数的定义

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
1
2
3
4
5
6
7

# 提取 json 数据

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]
1
2
3
4
5
6
7
8
9
10

# 函数参数的默认值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) {
  // ... do stuff
};
1
2
3
4
5
6
7
8
9
10
11

# 遍历 Map 结构

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
2
3
4
5
6
7
8
9
编辑 (opens new window)
上次更新: 2023/02/07, 14:51:48
CSS的查询属性
es5的扩展

← CSS的查询属性 es5的扩展→

Theme by Vdoing | Copyright © 2021-2023 yuadh
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×