ES6基础入门

🌈ES6基础入门

⭕let和const

let:代替var,用于声明变量的关键字

const:用于声明常量的关键字

💡let、const与var的区别

1. 重复声明:

​ var允许重复声明,但let和const不允许

2.变量提升:

​ var存在变量提升,但let和const不存在变量提升(会报错)

3.暂时性死区:

​ 只要作用域内存在let、const,它们声明的变量或常量就自动“绑定“这个区域,不再受到外部作用域的影响,即let和const存在暂时性死区

4.window对象的属性和方法:

​ 全局作用域中,var声明的变量会成为window对象的属性,function声明的函数会成为window对象的方法,而let和const不会

5.块级作用域:

​ let、const有块级作用域,并且会根据作用域链从内往外被访问到,而var没有块级作用域

⭕模版字符串与箭头函数

💡模板字符串

const str = ‘abc’; // 普通字符串

const str = `abc`; // 模板字符串

实际应用中:

const name = ‘小明’;

const age = 19;

document.body.innerHTML =`我的名字是${name},今年${age}岁了`

❗模板字符串的注意事项

1.输出多行字符串

使用 \n 实现换行:console.log(`第一行\n第二行`)

2.输出`和\等字符

使用\进行转义:console.log(`\``); // `

3.模板字符串的注入

只要最终可以得出一个值的就可以通过${}注入到模板字符串中

⭕箭头函数

💡认识箭头函数

语法:const 函数名 = 参数 => 函数体

将一般函数改写为箭头函数:

const fun = function () {} —改写—> const fun = () => {}

❗箭头函数的注意事项

**1.单个参数体 **——括号可省略

2.单行函数体——函数体是单行return语句,可以省略花括号

3.单行对象——如果返回单行对象,可以在{}外面加上(),让浏览器不再认为那是函数体的花括号

💡this指向

📍全局作用域中的this指向

1
console.log(this);  // window

📍一般函数(非箭头函数)中的this指向

1
2
3
4
5
6
7
8
9
'use strict'  // 开启严格模式
function fun () {
console.log(this); // 不知道this指向谁
};

fun(); // undefined ---> window (非严格模式下)
window.fun();
// 只有在函数调用的时候this指向才确定,不调用的时候,不知道指向谁
// this指向和函数在哪儿没关系,只和谁在调用有关

📍箭头函数中的this指向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const fun = () => {
console.log(this); // 箭头函数没有自己的this
};
// 例1:
const obj = {
add: () => {
console.log(this);
}
};
obj.add(); // window对象 this会顺着作用域链往外找
// 例2:
const cale = {
add: function () {
const fun = () => {
console.log(this)
};
fun();
}
}
cale.add(); // cale
const caleFn = cale.add;
caleFn(); // undefined ---> window

💡不适用箭头函数的场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 1.作为构造函数
const Person = () => {};
new Person(); // 报错; 箭头函数没有this,但构造函数最重要的就是this

// 2.需要this指向调用对象的时候
document.addEventListener('click',function(){
console.log(this); // 一般函数的this指向了document
});
document.addEventListener('click',() => {
console.log(this); // 箭头函数中的this指向了undefined ---> window
});

// 3.需要使用arguments的时候
// 箭头函数中没有arguments
function fun () {
console.log(arguments);
};
fun(1,2,3,4); // [1,2,3,4]

const fun1 = () => {
console.log(arguments);
}
fun1(1,2,3,4); // 报错

⭕数组的解构赋值

含义:解析某一数据的结构,将需要的提取出来,赋值给变量或者常量

原理:模式(结构)匹配;索引值相同的完成赋值

💡数组解构赋值的默认值

默认值的基本用法:const [a,b,c] = [1,2,3]

默认值的生效条件:只有当一个数组成员严格等于(===) undefined时,对应的默认值才会生效

默认值表达式:如果默认值是表达式,默认值表达式是惰性求值的

💡数组解构赋值的应用

📍1.常见的类数组的解构赋值

arguments和NodeList

📍2.函数参数的解构赋值

1
2
3
4
const arr = [1,2];
//const add = arr => arr[0] + arr[1];
const add = ([x,y]) => x + y;
cosole.log(add(arr));

📍3.交换变量的值

1
2
3
4
5
6
7
8
9
10
11
12
let x = 1;
let y = 2;

// 传统做法
let temp = x;
x = y;
y = temp;
console.log(x,y);

// 使用解构赋值
const [y,x] = [x,y];
console.log(x,y);

⭕对象的解构赋值

💡对象解构赋值的原理

1.模式(结构)匹配: {} = {}

2.属性名相同的完成赋值:

​ 简写:const {username, age} = {username: ‘小明’, age: 18};

​ 完整的:const {‘username’: username, ‘age’:age} = {username: ‘小明’, age: 18};

取别名: const {username: uname, age} = {username: ‘小明’, age: 18}; // 变量后 ‘ : ‘ 别名

💡对象结构赋值的注意事项

1.默认值的生效条件

​ 对象的属性严格等于(===) undefined时,对应的默认值才会生效

2.默认值表达式

​ 如果默认值是表达式,默认值表达式是惰性求值的

3.将一个已经声明的变量用于解构赋值

​ 如果将一个已经声明的变量用于解构赋值,整个赋值需要再圆括号中进行

​ let x = 1;

​ ({x}) = {x:2};

4.可以取到继承的属性

​ const {toString} = {};

​ console.log(toString); // 可以取到这个方法,因为toString方法是Object身上的

💡对象解构赋值的应用

📍1.函数参数的解构赋值

1
2
3
4
5
6
// 传统做法
const fun = user => console.log(user.username, user.age);
fun({username: '李四', age: 19});
// 使用解构赋值
const fun = ({age = 15, username = '张三'}) => console.log(username, age);
fun({username: '李四', age: 19});

📍2.复杂的嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const obj = {
x:1,
y: [2,3,4],
z: {
a: 5,
b: 6
}
};
const {
y,
y: [,yy],
z,
z: {
b
}
} = obj;
console.log(yy,y,z,b);

⭕其他数据类型的解构赋值

💡字符串的解构赋值

1
2
3
4
5
6
7
8
// 数组形式的解构赋值
const [a,,,b,c] = 'hello';
console.log(a,b,c);
// 对象形式的解构赋值
const {0:a,1:b,length} = 'hello';
console.log(a,b,length);]

//字符串既可以按照数组形式来解构赋值,也可以按照对象的形式来解构赋值

💡数值和布尔值的解构赋值

会先将数值或者布尔值转换为对象,然后在进行解构赋值(转换为对象后,什么内容都没有!)

💡undefined 和 null 的解构赋值

由于undefined 和 null 没有对应的包装对象,所以无法通过它们转换成相应的对象,所以对他们进行解构赋值,都会报错

⭕对象字面量的增强

📍属性的简洁表示法

当键名和变量或者常量名一样的时候,可以只写一个

1
2
3
4
5
6
const age = 18;
const person = {
//'age':age
//简写
age
};

📍方法的简洁表示法

方法可以省略冒号和function关键字

1
2
3
4
5
const person = {
//speak: function () {console.log('hello');}
//简写
speak(){console.log('hello');}
};

💡函数参数的默认值

📍认识函数参数的默认值:调用函数的时候传参了,就用传递的参数;如果没传参,就用默认值

📍函数参数默认值的基本用法

1
const fun (x = 1, y = 2) => x * y;

💡函数参数默认值的注意事项

📍默认值的生效条件:不传参数,或者明确的传递undefined作为参数,只有这两种情况,默认值才生效

📍默认值表达式:如果默认值是表达式,默认值表达式是惰性求值的

📍设置默认值的小技巧:函数参数的默认值,最好从参数列表的右边开始设置

💡函数参数默认值的应用

  1. 接收很多参数的时候

    1
    2
    const fun = (username = '张三', age = 18, gender = '男') => console.log(username, age, gender);
    fun('李四', 22, '女');
  2. 接收一个对象作为参数

    1
    2
    3
    4
    5
    6
    //const fun = student => console.log(student.username, student.age, student.gender);
    //fun({username: '李四', age: 22, gender: '女'});

    const fun = ({username = '张三', age = 18, gender = '男'} = {}) => console.log(username, age, gender);
    fun({username: '李四', age: 22, gender: '女'});
    fun();

⭕剩余参数

含义:当函数接收参数的个数不确定时,可以使用剩余参数

形式:const fun = (x, y, …args) => {}

本质: 剩余参数永远都是一个数组,即使没有值,也是空数组

💡剩余参数的注意事项

1.箭头函数的剩余参数

​ 箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号

2.使用剩余参数替代arguments获取实际参数

​ const fun = (…args) => {console.log(args);};

3.剩余参数的位置

​ 剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错

💡剩余参数的应用

📍1.完成add函数

1
2
3
4
5
6
7
8
9
10
11
12
// 1.完成add函数
// const add = (...args) => {
// let result = 0;
// for (const item of args) {
// result += item;
// }
// return result;
// };

// 使用数组的reduce方法
const add = (...args) => args.reduce((prev, next) => prev + next);
console.log(add(1, 2, 3));

📍2.与解构赋值结合使用

1
2
3
4
5
6
7
8
// 剩余参数不一定非要作为函数参数使用
const [a,...args] = [1,2,3,4];
console.log(a,args); // 1, [2,3,4]
// 剩余参数必须是最后一个

const {x,y,...z} = {a: 3, x: 1, y: 2, b: 4};
console.log(x, y, z); // 1, 2, {a: 3, b: 4}
// 在数组和对象解构赋值中使用,称为剩余元素

⭕数组展开运算符

基本用法:

例如找到数组中的最小值,可以使用Math.min(),但其参数是数字列表,可以使用展开运算符实现将数组展开为数字列表

consolo.log(Math.min(…[4, 2, 3])); 相当于 console.log(Math.min(4, 2, 3))

💡区分剩余参数和展开运算符

根本区别:

​ 展开运算符:[1, 2, 3] —> 1, 2, 3

​ 剩余参数:1, 2, 3 —> [1, 2, 3]

⭕对象展开运算符

1,展开对象

​ 对象不能直接展开,必须在{}中展开

​ 对象的展开:把属性罗列出来,用逗号分隔,放到一个{}中,构成新对象

2.合并对象

​ const obj1 = {……} , const obj2 = {……}

​ console.log({…obj1, …obj2});

​ 新对象拥有全部属性,相同属性,后者覆盖前者

💡对象展开运算符的注意事项

1.空对象的展开

​ 如果展开一个空对象,则没有任何效果

2.非对象的展开

​ 如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来

​ 如果展开运算符后面是字符串,他会自动转成一个类似数组的对象,因此返回的不是空对象

3.对象中对象属性的展开

​ 不会展开对象中的对象属性

💡对象展开运算符的应用

📍1.复制对象

1
2
3
4
5
6
7
8
9
// 1.复制对象
const obj1 = {
name: '张三',
age: 18,
gender: '男',
};
const obj2 = { ...obj1 };
console.log(obj2); // {name: '张三', age: 18, gender: '男'}
console.log(obj2 === obj1); // false

📍用户参数和默认参数

1
2
3
4
5
6
7
8
9
10
11
12
// 用户参数和默认参数
const loUser = userParam => {
// 默认参数
const defaultParam = {
username: 'zhangsan',
age: 19,
gender: '男',
};

const { username, age, gender } = { ...defaultParam, ...userParam };
console.log(age, username, gender);
};

⭕Set 和 Map 数据结构

💡认识Set

含义:Set是一系列无序、没有重复值的数据集合,即Set中不能有重复的成员,Set没有下标去标识每一个成员

💡Set实例的方法和属性

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
const s = new Set();

// 1.方法
// add : 新增一个成员
s.add(1).add(2).add(2);
console.log(s); // Set(2) {1, 2}

// has : 检查是否存在某个成员,返回布尔值
console.log(s.has(1)); // true
console.log(s.has(3)); // false

// delete : 删除指定的成员,如果删除不存在的成员,什么都不会发生,也不会报错
// s.delete(1);
// s.delete(3);
// console.log(s);

// clear : 全部删除Set中成员
// s.clear();
// console.log(s);

// forEach : 遍历Set,提供了访问Set成员的方式
s.forEach(function (value, key, set) {
// Set 中的value 等于 key
console.log(this); // 指向document
},document);

// 按照成员添加进集合的顺序遍历

// 2.属性
// size : Set中的成员个数
console.log(s.size); // 2

💡Set构造函数的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1.数组
// const s = new Set([1, 2, 1]);
// console.log(s); // Set(2) {1, 2}

// 2.字符串、arguments、NodeList、Set
// const s = new Set('hello');
// console.log(s); // Set(4) {'h', 'e', 'l', 'o'}
// const fun = function (params) {
// console.log(new Set(arguments)); // Set(2) {3, 4}
// };
// fun(3, 4, 3);

// const s = new Set(document.querySelectorAll('p'));
// console.log(s);
// s.forEach(elem => elem.style.backgroundColor = 'orange')

const s = new Set([1, 2, 3, 1]);
console.log(new Set(s)); // Set(3) {1, 2, 3}
console.log(new Set(s) === s); // false

💡Set 的注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 1.判断重复的方式
// const s = new Set([1, 2, 1]);
// console.log(s); // Set(2) {1, 2}

// const s = new Set([NaN, 1, NaN]);
// console.log(s); // Set(2) {NaN, 1}

// console.log(NaN === NaN); // false

// Set 对重复值的判断基本遵循严格相等(===)
// 但是对于 NaN 的判断与 === 不同,Set 中 NaN 等于 NaN

const s = new Set();
s.add({}).add({});
console.log({} === {}); // false
console.log(s); // {{…}, {…}}

// 2.什么时候使用Set
// ①数组或字符串去重时
// ②不需要通过下标访问,只需要遍历时
// ③为了使用 Set 提供的方法和属性时(add, has, delete, clear, forEach, size等)

💡Set 的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 1.数组去重
// [1,2,1]
// const s = new Set([1, 2, 1]);
// console.log(s);
// s.forEach

// console.log([...s]);
// console.log([...new Set([1, 2, 1])]);

// 2.字符串去重
// 'abbacbd'
// const s = new Set('abbacbd');
// console.log([...s].join(''));

// console.log([...new Set('abbacbd')].join(''));

// 3.存放 DOM 元素
// const s = new Set(document.querySelectorAll('p'))
// for()
const s = new Set(document.querySelectorAll('p'))
s.forEach(elem => {
elem.style.color = 'red'
elem.style.backgroundColor = 'yellow'
})

💡认识Map

含义:键值对的集合,可以称作映射

形式:键 -> 值,key -> value

❗Map和对象的区别

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
// 对象一般用字符串当作键
const obj = {
name: 'zhangsan',
age: 19,
[{}]: 'object',
};
console.log(obj);
console.log({}.toString());

// Map中的键可以是基本数据类型,也可以是引用数据类型
// 基本数据类型:数字、字符串、布尔值、undefined、null
// 引用数据类型:对象({}、[]、函数、Set、Map等)
const m = new Map();
m.set('name', 'lisi');
m.set('age', 18);
m.set(true, 'true');
m.set(undefined, 'undefined');
m.set(null, 'null');
m.set({},'object')
m.set([],'array')
m.set((x,y)=>x+y,'function')
m.set(new Set([1,2,3]),'set')
m.set(new Map(),'map')

console.log(m);

💡Map实例的方法和属性

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
const m = new Map();
// 1.方法
// set : 添加成员
m.set('name', 'zhangsan').set('age', 19).set('gender', '男');
console.log(m);

// get : 根据键得到值,如果获取的不存在,返回undefined
console.log(m.get('age'));

// has : 是否有这个键,返回true / false
console.log(m.has('gender'));

// delete : 根据键删除成员,删除不存在的成员,什么也不发生,也不报错
// m.delete('gender')
// console.log(m)

// clear : 清空整个Map
// m.clear()
// console.log(m)

// forEach : 遍历Map
m.forEach(function (value,key,map) {
console.log(value,key,map)
console.log(this)
},document)

// 2.属性
// size : 成员个数
console.log(m.size)

💡Map构造函数的参数

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
// 1.数组
// 只能传二维数组,而且必须体现键值对
// const m = new Map([
// ['name', 'zhangsan'],
// ['age', 19],
// ['gender', 'male'],
// ]);
// console.log(m);

// 2.Set、Map 等
// Set 中必须体现出键和值
// const s = new Set([
// ['name', 'zhangsan'],
// ['age', 19],
// ['gender', 'male'],
// ]);
// console.log(new Map(s));

// Map
// 复制一个新Map
const m = new Map([
['name', 'zhangsan'],
['age', 19],
['gender', 'male'],
]);

console.log(new Map(m) === m); // false
console.log(new Map(m));

💡Map的注意事项

1
2
3
4
5
6
7
8
9
// 1.判断键名是否相同的方式
// 基本遵循严格相等(===)
// 例外就是 NaN,Map 中 NaN 也是等于 NaN
const m = new Map();
m.set(NaN,1).set(NaN,2);
console.log(m); // Map(1) {NaN => 2}

// 2.什么时候使用Map
// 如果只是需要 key -> value 的结构,或者需要字符串以外的值做键,使用Map更合适

💡Map的应用

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
const [p1, p2, p3] = document.querySelectorAll('p');
// const m = new Map([
// [p1, 'red'],
// [p2, 'yellow'],
// [p3, 'pink'],
// ]);

// m.forEach((color, elem) => {
// elem.style.backgroundColor = color;
// });

const m = new Map([
[
p1,
{
color: 'red',
backgroundColor: 'yellow',
fontSize: '30px',
},
],
[
p2,
{
color: 'yellow',
backgroundColor: 'pink',
fontSize: '16px',
},
],
[
p3,
{
color: 'pink',
backgroundColor: 'blue',
fontSize: '23px',
},
],
]);
m.forEach((elemStyle, elem) => {
console.log(elemStyle)
for (const propStyle in elemStyle) {
elem.style[propStyle] = elemStyle[propStyle];
}
});

⭕遍历器与for…of循环

💡认识Iterator

作用:Iterator称为遍历器(迭代器),用于遍历的一种方式

寻找Iterator:console.log( [1,2][Symbol.Iterator]() ); // Array Iterator {}

📍使用Iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 找到Iterator
// const it = [1, 2][Symbol.iterator]();
// console.log(it); // Array Iterator {}

// 使用Iterator
const it = [1, 2][Symbol.iterator]();
console.log(it.next()); // {value: 1, done: false}
console.log(it.next()); // {value: 2, done: false}
console.log(it.next()); // {value: undefined, done: true}
console.log(it.next()); // {value: undefined, done: true}

// it: 可遍历对象(可迭代对象)
// Symbol.iterator: 可遍历对象的生成方法

// 什么是Iterator
// Symbol.iterator(可遍历对象的生成方法)--> it(可遍历对象)--> it.next() --> it.next() --> ...(直到done 为 true)

💡Iterator疑惑

1.为什么需要Iterator 遍历器

遍历数组:for 循环 和 forEach 方法

遍历对象:for…in 循环

Iterator 遍历器是一个统一的遍历方式

2.如何更方便的使用Iterator

一般不会直接使用Iterator去遍历,已经封装好了一套 —— for…of 循环

💡认识for…of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 认识for...of
// for...of的本质:就是将Iterator循环遍历的过程封装起来

// 拿到iterator
const arr = [1, 2, 3];
// const it = arr[Symbol.iterator]();
// let next = it.next();
// console.log(next); // {value: 1, done: false}

// // 使用while自动化执行iterator,直到value为undefined,也就是done为true
// while (!next.done) {
// console.log(next.value);
// next = it.next();
// }

// 将上面的过程封装起来就是 for...of
for (const item of arr) {
console.log(item);
}

// for...of循环只会遍历出那些done为false时,对应的value值

💡for…of的用法

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
const arr = [1, 2, 3];
// 1.与break、continue一起使用
// for (const item of arr) {
// // if(item === 2) break;
// if (item === 2) continue;
// console.log(item);
// }

// 2. key() : 在for...of 中获得数组的索引
for (const index of arr.keys()) {
// console.log(index);
}

// 3. values() : 在for...of 中获得数组的值
for (const value of arr.values()) {
// console.log(value);
}

// 4. entries() : 得到索引 + 值组成的数组的可遍历对象
// for (const entries of arr.entries()) {
// console.log(entries); // 数组
// }

// 可以使用解构直接拿到 value 和 key
for (const [key,value] of arr.entries()) {
console.log(key,value);
}

💡原生可遍历和非原生可遍历

1.什么是可遍历

​ 只要有 Symbol.iterator() 方法,并且这个方法可以生成可遍历对象,就是可遍历的

只要是可遍历对象,就可以使用for…of 循环来统一遍历

2.原生可遍历有哪些

​ ①数组 ②字符串 ③Set ④Map ⑤arguments ⑥NodeList

3.非原生可遍历有哪些

​ ①一般的对象 —— 直接使用 for…in 遍历即可(不建议手搓Symbol.iterator方法)

⭕ES6新增方法

💡字符串的新增方法

🐼includes()

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
// includes() : 判断字符串中是否包含某些字符

// 1.基本用法
console.log('abc'.includes('a')); // true
console.log('abc'.includes('ab')); // true
console.log('abc'.includes('bc')); // true
console.log('abc'.includes('ac')); // false

// 2.第二个参数
// 表示开始搜索的位置,默认是0
console.log('abc'.includes('a', 0)); // true
console.log('abc'.includes('a', 1)); // false

// 3.应用 ———— 地址栏拼接
// https://yubai.eu.org
// https://yubai.eu.org?username=admin&password=123456

// let url = 'https://yubai.eu.org';
let url = 'https://yubai.eu.org?';
// 创建函数,处理拼接,传入的参数为拼接的内容
const urlConcat = (url, key, value) => {
// 判断最后一位是不是?
if(url[url.length-1] === '?'){
url += `${key}=${value}`;
return url
} else {
// 判断url是否包含?
url += url.includes('?')? '&' : '?';
url += `${key}=${value}`;
return url;
}
};
url = urlConcat(url, 'name', 'admin');
url = urlConcat(url, 'password', '123456');
console.log(url);

🐼padStart() 和 padEnd()

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
// 补全字符串长度

// 1.基本用法
console.log('x'.padStart(5, 'ab')); // ababx
console.log('x'.padEnd(5, 'ab')); // xabab
console.log('x'.padEnd(4, 'ab')); // xaba

// 2.注意事项
// 原字符串的长度,等于或者大于最大长度,不会消减原字符串,字符串补全不生效,返回原字符串
console.log('xxx'.padStart(2, 'ab')); // xxx
console.log('xxx'.padEnd(2, 'ab')); // xxx

// 用来补全的字符串与原字符串长度之和超过了最大长度,截取超出位数的补全字符串,原字符串不动
console.log('xxx'.padStart(10, '0123456789')); // 0123456xxx
console.log('xxx'.padEnd(10, '0123456789')); // xxx0123456

// 如果省略第二个参数,默认使用空格补全长度
console.log('x'.padStart(4)); // ' x'
console.log('x'.padEnd(4)); // 'x '

// 3.应用
// 显示日期格式 :月份和日期个位数时,进行补零的操作
const date = new Date();
const year = date.getFullYear()
const Month = date.getMonth() + 1
const day = date.getDate()

console.log(`今天的日期:${year}-${Month.toString().padStart(2,'0')}-${day.toString().padStart(2,'0')}`);

🐼trimStart() 和 trimEnd()

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" name="" id="content">
<input type="submit" value="提交" id="btn">
<script>
// 清除字符串的首或尾空格,中间的空格不会清除

// 1.基本用法
const str = ' a b c ';
console.log(str.trimStart()); // 'a b c '
console.log(str.trimEnd()); // ' a b c'
// 别名
console.log(str.trimLeft()); // 'a b c '
console.log(str.trimRight()); // ' a b c'
console.log(str.trim()); // 'a b c'

// 2.应用 ———— 表单提交前的判空
const content = document.getElementById('content')
const btn = document.getElementById('btn')

btn.addEventListener('click',()=>{
// 判空
if (!content.value.trim()) return alert('提交不通过')
alert('提交通过')
})
</script>
</body>
</html>

💡数组的新增方法

🐼includes()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1.判断数组中是否含有某个成员
console.log([1, 2, 3].includes('2')); // false
console.log([1, 2, 3].includes(2)); // true
// 第二个参数表示搜索的起始位置,默认值是0
console.log([1, 2, 3].includes(2, 2)); // false
// 基本遵循严格相等(===),但是对于 NaN 的判断与 === 不同,includes认为 NaN 等于 NaN

// 2.应用
// 去重
const arr = [1, 2, 1];
const result = [];
for (const item of arr) {
if (!result.includes(item)) {
result.push(item);
}
}
console.log(result);

🐼Array.from()

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
// Array.from()
// 将其他数据类型转换为数组

// 1.基本用法
console.log(Array.from('str')); // ['s', 't', 'r']

// 2.哪些可以通过 Array.from() 转换成数组
// 2.1.所有可遍历的
// 数字、字符串、Set、Map、arguments、NodeList
console.log(Array.from(new Set([1, 2, 1]))); // [1, 2]
console.log([...new Set([1, 2, 1])]); // [1, 2]

// 2.2.拥length 属有 性的任意对象
const obj = {
0: 'a',
1: 'b',
name: 'Lisa',
length: 3,
};
console.log(Array.from(obj));
// console.log([...obj]); // 错误写法

// 3.第二个参数
// 作用类似于数组的 Map 方法,用来对每个元素进行处理,将处理后的值放入返回的数组
console.log(
[1, 2].map(value => {
return value * 2; // [2,4]
})
);
console.log(Array.from([1, 2], value => value * 2)); // [2,4]
console.log([1, 2].map(value => value * 2)); // [2,4]

// 4.第三个参数
// 修改this指向
console.log(
Array.from(
[1, 2],
function () {
console.log(this);
},
document
)
);

🐼find() 和 findIndex()

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
// find() : 找到满足条件的一个立即返回
// findIndex() : 找到满足条件的一个,立即返回其索引

// 1.基本用法
console.log(
[1, 5, 16, 23].find((value, index, arr) => {
// console.log(value, index, arr);
return value > 9;
})
);
console.log(
[1, 5, 16, 23].findIndex((value, index, arr) => {
// console.log(value, index, arr);
return value > 9;
})
);

// 2.第二个参数————改变this指向
console.log(
[1, 5, 16, 23].find(function (value, index, arr) {
console.log(this);
}, document)
);

// 3.应用 : 筛选出需要的信息
const students = [
{
name: '张三',
age: 18,
gender: '男',
},
{
name: '李四',
age: 12,
gender: '男',
},
{
name: '小美',
age: 22,
gender: '女',
},
];
console.log(students.find((value, index) => value.gender == '女'));
console.log(students.findIndex((value, index) => value.gender == '女'));

💡对象的新增方法

🐼Object.assign()

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
48
49
50
51
52
53
54
55
56
57
// 1.用来合并对象
// 基本用法: Object.assign(目标对象, 源对象1,源对象2...,源对象n);
// const apple = {
// color: '红色',
// shape: '圆形',
// taste: '甜',
// };
// const pen = {
// color: '黑色',
// shape: '圆柱体',
// use: '写字',
// };
// console.log(Object.assign(apple, pen)); // {color: '黑色', shape: '圆柱体', taste: '甜', use: '写字'}
// Object.assign直接合并到了第一个参数中,返回的就是合并后的对象
// console.log(apple); // {color: '黑色', shape: '圆柱体', taste: '甜', use: '写字'}
// console.log(Object.assign(apple, pen) === apple); // true

// 可以合并多个对象
// console.log(Object.assign({}, apple, pen)); // {color: '黑色', shape: '圆柱体', taste: '甜', use: '写字'}
// console.log(apple); // {color: '红色', shape: '圆形', taste: '甜'}

// 2.注意事项
// 2.1.基本数据类型作为源对象
// 与对象的展开类似,先转换成对象,再合并
console.log(Object.assign({}, undefined)); // {}
console.log(Object.assign({}, null)); // {}
console.log(Object.assign({}, 123)); // {}
console.log(Object.assign({}, true)); // {}
console.log(Object.assign({}, 'string')); // {0: 's', 1: 't', 2: 'r', 3: 'i', 4: 'n', 5: 'g'}

// 2.2.同名属性的替换
// 后面的覆盖前面的
const apple = {
color: ['红色', '黄色'],
shape: '圆形',
taste: '甜',
};
const pen = {
color: ['黑色', '蓝色'],
shape: '圆柱体',
use: '写字',
};
console.log(Object.assign(apple, pen)); // {color: ['黑色', '蓝色'], shape: '圆柱体', taste: '甜', use: '写字'}

// 3.应用
// 合并默认参数和用户参数
const logUser = userOptions => {
const DEFAULTS = {
username: 'zhangsan',
age: 18,
gender: 'male',
};

return Object.assign({}, DEFAULTS, userOptions);
};

console.log(logUser({ username: '李华', age: 25 })); // {username: '李华', age: 25, gender: 'male'}

🐼Object.keys() 、Object.values() 、Object.entries()

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
// 1.基本用法
const student = {
name: 'zhangsan',
age: 19,
gender: 'male',
};
console.log(Object.keys(student)); // ['name', 'age', 'gender']
console.log(Object.values(student)); // ['zhangsan', 19, 'male']
console.log(Object.entries(student)); // [['name','zhangsan'], ['age',19], ['gender','male']]

// 2.与数组类似方法的区别
console.log([1, 2].keys()); // Array Iterator {}
console.log([1, 2].values()); // Array Iterator {}
console.log([1, 2].entries()); // Array Iterator {}

// 数组的 keys(),values(),entries() 等方法是实例方法,返回的都是Iterator可遍历对象
// 对象的 Object.keys()、Object.values()、Object.entries() 等方法是构造函数的方法,返回的是数组

// 3.使用for...of 循环遍历对象
const person = {
name: 'zhangsan',
age: 18,
gender: 'male',
};
for (const value of Object.values(person)) {
console.log(value);
}
for (const key of Object.keys(person)) {
console.log(key);
}
// for(const entries of Object.entries(person)){
// console.log(entries)
// }
for (const [key, value] of Object.entries(person)) {
console.log(key, value);
}

// Object.keys()、Object.values()、Object.entries() 并不能保证顺序一定是你看到的样子,这一点和for...of是一样的