ES6

ES6

1. ES6相关概念

1.1 什么是ES6

image-20230501200253213

1.2 为什么使用 ES6

image-20230501200306630

2. ES6新增语法

2.1 let

2.11 let声明的变量只在所处于的块级有效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 使用let关键字声明的变量具有块级作用域
let a = 10;
console.log(a);

if (true) {
let b = 20;
console.log(b);
if (true) {
let c = 30;
}
console.log(c);//c is not defined

}
console.log(b);//b is not defined

// 注意:使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
if (true) {
var num = 200;
let num2 = 300;
}
console.log(num);
console.log(num2);//num2 is not define

2.12 不存在变量提升

image-20230501200818845

1
2
3
4
5
6
7
8
9
10
11
12
// 使用let关键字声明的变量没有变量提升,只能先声明再使用
console.log(data);//cannot access 'data' before initialization
let data=100

// var变量提升
// console.log(num);
// var num = 123
// 相当于
var num
console.log(num);
num = 123
// 这是因为当使用var关键字声明变量时,变量声明会被提升到其所在作用域的顶部,但是变量赋值的语句不会被提升。

2.13 暂时性死区

image-20230501200941573

1
2
3
4
5
6
// 使用let关键字声明的变量具有暂时性死区特性
var num = 123;
if (true) {
console.log(num);//cannot access 'num' before initialization 初始化前无法访问“num”
let num = 20;//let绑定了整个if结构
}

2.14 防止循环变量变成全局变量

1
2
3
4
5
6
7
8
9
10
// 防止循环变量变成全局变量
for (var i = 0; i < 5; i++) {

}
console.log(i);//5

for (let j = 0; j < 2; j++) {

}
console.log(j);//j is not definedh

2.15 经典面试题

  • var

image-20230501201115919

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//2
arr[1]();//2
// 经典面试题图解:此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值。
// 全局作用下i的值是循环产生的,当终止循环结束的值就是i的值
// 这里使用的是var关键字来声明循环变量i,这意味着i是一个全局变量,而不是块级作用域变量。
// 因此,在循环结束后,i的值将保留为其最后一次迭代的值,即2。
// 这意味着无论调用arr[0]()还是arr[1](),它们都会打印2,而不是0或1。
  • let

image-20230501201211067

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//0
arr[1]();//1
// 因为使用let关键字声明的变量具有块级作用域,所以在每次循环迭代中,都会创建一个新的i变量实例,
// 它们在每次迭代时都有不同的作用域。这使得每个函数都能够访问到其创建时的唯一i值,而不是在循环结束时的i值。
// 最后,代码通过使用数组索引运算符调用arr[0]()和arr[1]()来分别执行数组中的第一个和第二个函数。
// 由于第一个函数是在循环中创建并且在循环中i的值为0,因此调用arr[0]()将打印0。同样,第二个函数是在循环中创建并且在循环中i的值为1,因此调用arr[1]()将打印1。

2.16 小结

  • let关键字就是用来声明变量的
  • 使用let关键字声明的变量具有块级作用域
  • 在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
  • 防止循环变量变成全局变量
  • 使用let关键字声明的变量没有变量提升
  • 使用let关键字声明的变量具有暂时性死区特性

2.2 const

2.21 变量常量

作用
常量和变量都是在编程中用于存储数据值的标识符

变量
变量是一种可变的标识符,用于存储可以更改的值。在程序执行期间,变量的值可以随时更改。
变量通常使用var、let或const关键字来声明。在JavaScript中,变量的作用域可以是全局的或局部的,具体取决于它们是在函数内部声明还是在函数外部声明。

常量
常量是一种不可变的标识符,用于存储不可更改的值。在程序执行期间,常量的值不能被修改。
常量通常使用const关键字来声明。在JavaScript中,常量的作用域可以是全局的或局部的,具体取决于它们是在函数内部声明还是在函数外部声明。

目的
使用常量和变量的主要目的是为了使代码更易于理解和维护。通过将值存储在常量或变量中,可以避免在代码中多次使用相同的值,并且可以在需要时更轻松地更改这些值。

2.22 具有块级作用域

image-20230501201847551

2.23 声明常量时必须赋值

image-20230501201856523

2.24 常量赋值后,值不能修改

1
2
3
4
5
6
7
8
9
10
11
// 常量赋值后,值不能修改
// 基本数据类型
const PI = 3.14;
PI = 100; // Assignment to constant variable.

// // 复杂数据类型
const ary = [100, 200];
ary[0] = 'a';//复杂数据类型里的值可以更改
ary[1] = 'b';
console.log(ary); // ['a', 'b'];
ary = ['a', 'b']; // Assignment to constant variable.不能直接赋值

2.25 小结

  • const声明的变量是一个常量
  • 既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
  • 声明 const时候必须要给定值

2.3 let、const、var 的区别

image-20230501202459068

let、const和var都是用于声明变量的关键字,但它们之间存在一些重要的区别。

1.变量作用域

var: 使用var声明的变量具有函数作用域或全局作用域。在函数内声明的变量只在该函数内部可见,而在函数外部声明的变量则在整个程序中都可见。
let和const: 使用let或const声明的变量具有块级作用域。在块级作用域内声明的变量只在该块内部可见,而在块外部则不可见。

2.变量提升

var: 使用var声明的变量会被提升到其所在函数或全局作用域的顶部。这意味着可以在变量声明之前引用变量,但是变量的值为undefined。
let和const: 使用let或const声明的变量不会被提升。在变量声明之前引用变量会导致ReferenceError错误。

3.变量重复声明

var: 使用var可以重复声明同一个变量,而后面的声明会覆盖前面的声明。
let和const: 使用let或const在同一作用域内重复声明同一个变量会导致SyntaxError错误。

4.变量赋值

var和let: 使用var或let声明的变量可以被重新赋值。
const: 使用const声明的变量不能被重新赋值。这意味着一旦用const声明变量,就不能再更改它的值。

综上所述,使用let和const声明变量可以更安全、可预测和易于维护,因为它们提供了更严格的作用域规则和不可变的变量。而var则可能导致意外的行为,因为它的作用域和变量提升规则比较宽松。

2.4 解构赋值

image-20230501202658386

2.41 数组解构

image-20230501202732370

1
2
3
4
5
6
7
8
9
10
11
12
13
// 数组解构允许我们按照一一对应的关系从数组中提取值 然后将值赋值给变量
// ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构
let ary = [1, 2, 3];
let [a, b, c, d, e] = ary;
console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)

// 解构赋值是一种在编程中使用的语法特性,它允许将数组或对象中的值解构为单独的变量。
// 这种技术可以使得从数组或对象中提取数据变得更为简单和方便。
// 在 JavaScript 中,解构赋值通常使用花括号 { } 表示对象解构,方括号[] 表示数组解构。

2.42 对象解构

image-20230501202806703

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 对象解构允许我们使用变量的名字匹配对象的属性 匹配成功 将对象属性的值赋值给变量

let person = {
name: 'lisi',
age: 30,
sex: '男'
};
// let { name, age, sex } = person;
// console.log(name)
// console.log(age)
// console.log(sex)

let { name: myName } = person;
console.log(myName)

// - 解构赋值就是把数据结构分解,然后给变量进行赋值
// - 如果结构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
// - 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
// - 利用解构赋值能够让我们方便的去取对象中的属性跟方法

2.43 小结

  • 解构赋值就是把数据结构分解,然后给变量进行赋值
  • 如果结构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
  • 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
  • 利用解构赋值能够让我们方便的去取对象中的属性跟方法

2.5 箭头函数

2.51 简化函数

箭头函数是用来定义语法的

image-20230501202937082

1
2
3
4
5
6
// () => {} //():代表是函数; =>:必须要的符号,指向哪一个代码块;{}:函数体
// const fn = () => {}//代表把一个函数赋值给fn
const fn = () => {
console.log(123)
}
fn();

2.32 大括号省略

在箭头函数中 如果函数体中只有一句代码 并且代码的执行结果就是函数的返回值 函数体大括号可以省略

image-20230501203328581

1
2
3
const sum = (n1, n2) => n1 + n2;	 
const result = sum(10, 20);
console.log(result)

2.33 小括号省略

在箭头函数中 如果形参只有一个 形参外侧的小括号也是可以省略的

image-20230501203416534

1
2
3
4
const fn = v => {
alert(v);
}
fn(20)

2.34 箭头函数this

箭头函数不绑定this ,箭头函数没有自己的this关键字, 如果在箭头函数中使用this, this关键字将指向箭头函数定义位置中的this

image-20230501203433161

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn() {
console.log(this);
return () => {
console.log(this)//window
}
}

const obj = { name: 'zhangsan' };

// call方法可以改变this指向,指向call(demo)里的参数demo
const resFn = fn.call(obj);

resFn();

2.6 剩余参数

2.61 解读

在 JavaScript 中,剩余参数也使用三个点号(…)表示,并且通常被称为 “rest parameters”。与 Python 中的剩余参数类似,JavaScript 中的剩余参数允许函数接受任意数量的参数,并将它们存储在一个数组中。

2.61 不定数量参数表示为一个数组

剩余参数语法允许我们将一个不定数量的参数表示为一个数组。

image-20230501203743278

1
2
3
4
5
6
7
8
9
10
11
// es6之前用函数配合其独有的arguments来使用不定长参数
// 可es6里的箭头函数是不能使用arguments的,用剩余参数

const sum = (...args) => {
let total = 0;
args.forEach(item => total += item);
return total;
};

console.log(sum(10, 20));
console.log(sum(10, 20, 30));

2.62 剩余参数和解构配合使用

image-20230501203840916

1
2
3
4
let ary1 = ['张三', '李四', '王五'];
let [s1, ...s2] = ary1;
console.log(s1)//张三
console.log(s2)//[李四, 王五]

3. ES6 的内置对象扩展

3.1 Array 的扩展方法

3.11 扩展运算符

  • 扩展运算符是ES6引入的一种语法特性,它使用三个点 … 表示,可以将一个数组或对象“展开”为多个元素或属性。

  • 扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。

    image-20230501204237844

  • 扩展运算符可以应用于合并数组。

    image-20230501204247856

  • 将类数组或可遍历对象转换为真正的数组

    image-20230501204301342

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="UTF-8">
    <title>扩展运算符</title>
    </head>

    <body>
    <div>1</div>
    <div>4</div>
    <div>3</div>
    <div>6</div>
    <div>2</div>
    <div>5</div>
    <script type="text/javascript">
    // 1.扩展运算符可以将数组拆分成以逗号分隔的参数序列
    // let ary = ["a", "b", "c"];
    // ...ary // "a", "b", "c"
    // console.log(...ary)
    // console.log("a", "b", "c")

    // 2.扩展运算符应用于数组合并
    // let ary1 = [1, 2, 3];
    // let ary2 = [4, 5, 6];
    // // ...ary1 // 1, 2, 3
    // // ...ary1 // 4, 5, 6
    // let ary3 = [...ary1, ...ary2];
    // console.log(ary3)

    // 3.合并数组的第二种方法
    // let ary1 = [1, 2, 3];
    // let ary2 = [4, 5, 6];

    // ary1.push(...ary2);
    // console.log(ary1)

    // 利用扩展运算符将伪数组转换为真正的数组
    var oDivs = document.getElementsByTagName('div');
    console.log(oDivs)
    var ary = [...oDivs];
    ary.push('a');
    console.log(ary);
    </script>
    </body>

    </html>

3.12 构造函数方法:Array.from()

  • 将类数组或可遍历对象转换为真正的数组

    image-20230501204448382

  • 方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

    image-20230501204455388

3.13 实例方法:find()

  • 用于找出第一个符合条件的数组成员,如果没有找到返回undefined

    image-20230501204507635

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var ary = [{
    id: 1,
    name: '张三'
    }, {
    id: 2,
    name: '李四'
    }];
    // 用于找出第一个符合条件的数组成员,如果没有找到返回undefined
    let target = ary.find(item => item.id == 3);//找数组里面符合条件的值,当数组中元素id等于2的查找出来,注意,只会匹配第一个
    console.log(target)//undefined

3.14 实例方法:findIndex()

  • 用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1

    image-20230501204552010

3.15 实例方法:includes()

  • 表示某个数组是否包含给定的值,返回布尔值。

    image-20230501204601270

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let ary = ["a", "b", "c"];
    // es6之前,使用indexOf方法判断某个数组是否包含给定的值
    for (let i = 0; i < ary.length; i++) {
    if (ary[i].indexOf('c') !== -1) {
    console.log('find!');
    }
    }
    // 判断某个数组是否包含给定的值,返回布尔值。
    let result = ary.includes('a')
    console.log(result)
    result = ary.includes('e')
    console.log(result)

3.2 String 的扩展方法

3.21 模板字符串

模板字符串是ES6引入的一种语法特性,它使用反引号(``)和${}符号来表示字符串中的变量或表达式。

模板字符串可以包含普通字符串和变量或表达式,其中变量或表达式使用 ${} 符号包裹起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 1.模板字符串:ES6新增的创建字符串的方式,使用反引号定义
let name = `张三`;

// 2.模板字符串中可以解析变量
let sayHello = `Hello, 我的名字叫${name}`;
console.log(sayHello);

// 3.模板字符串中可以换行
let result = {
name: "zhangsan",
age: 20
};
let demo = `
<div>
<span>${result.name}</span>
<span>${result.age}</span>
</div>
`;
console.log(demo);

// 4.在模板字符串中可以调用函数
const fn = () => {
return '我是fn函数'
}

let html = `我是模板字符串 ${fn()}`;
console.log(html)

3.22 实例方法:startsWith() 和 endsWith()

image-20230501205022861

1
2
3
4
5
6
7
8
//实例方法:startsWith() 和 endsWith()
// - startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
// - endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
let str = 'Hello ECMAScript 2015';
let r1 = str.startsWith('Hello');
console.log(r1);
let r2 = str.endsWith('2016');
console.log(r2)

3.23 实例方法:repeat()

image-20230501205048853

3.3 Set 数据结构

3.31 解读

image-20230501205105753

3.32 size方法

1
2
3
4
5
6
7
8
9
10
11
const s1 = new Set();
console.log(s1.size)//size,判断Set数据结构包含了多少值

const s2 = new Set(["a", "b"]);
console.log(s2.size)//2

// 可以利用size方法将数组去重
const s3 = new Set(["a", "a", "b", "b"]);
console.log(s3.size)//2
const ary = [...s3];
console.log(ary)//['a', 'b']

3.33 实例方法

image-20230501205151664

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const s4 = new Set();
// 1.向set结构中添加值 使用add方法
s4.add('a').add('b');
console.log(s4.size)//2

// 2.从set结构中删除值 用到的方法是delete
const r1 = s4.delete('c');
console.log(s4.size)//2
console.log(r1);//false

// 3.判断某一个值是否是set数据结构中的成员 使用has
const r2 = s4.has('d');
console.log(r2)//false

// 4.清空set数据结构中的值 使用clear方法
s4.clear();
console.log(s4.size);//0

3.34 遍历

image-20230501205220466

1
2
const s5 = new Set(['a', 'b', 'c']);
s5.forEach(value => console.log(value))//a b c