ES6笔记

ES6

ES6简介

  • ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言

  • 90%的浏览器都支持ES6,也可以通过 babel 编译器(一个 js 编译器)将 ES5 代码 转为 ES6 代码

let和const

  • let 声明变量没有变量提升
  • let 是一个块作用域,let声明的变量只在它所在的代码块有效。在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
  • let 不可以重复声明
  • const 声明常量,一旦声明就不能被修改,除此之外也有 let 的三个特性。

开发中,默认情况下用 const,而只有在你知道变量值需要被修改的情况下使用 let

模板字符串

  • 模板字符串:使用 tab 键的反引号 `
  • 插入变量时:使用 ${ 变量名 }
1
2
3
4
5
6
7
8
9
10
const oBox = document.querySelector('.box')
let id = 1, name = '牛肉粉';
// ES6 写法
let htmlStr = `<ul>
<li>
<p id = ${id} > ${name} </p>
</li>
</ul>`

oBox.innerHTML = htmlStr;

函数默认值和剩余参数

  • 函数默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function add(a = 10, b = 20){    //设置默认值
return a + b;
}
console.log(add()); // 30

function add(a, b = getVal(5)) { //默认值可以是函数
return a + b;
}

function getVal(val) {
return val + 5;
}

console.log(add(10));
  • 剩余参数 :由…和一个紧跟着的具名参数组成 : …keys
  • …keys 解决了 arguments 的问题
1
2
3
4
5
function checkArgs(...args){
console.log(args); // 返回一个真实的实参数组["a", "b", "c"]
console.log(arguments); // 返回一个实参伪数组
}
checkArgs('a','b','c');

扩展运算符

剩余参数与扩展运算符的区别:

  • 剩余参数:把多个独立的合并到一个数组中
  • 扩展运算符:将一个数组分割,并将各个项作为分离的参数传给函数
1
2
3
4
// Math.max 获取最大值 
const arr = [10, 20, 50, 30, 90, 100, 40];
// 扩展运算符更方便
console.log(Math.max(...arr)) // 100

箭头函数

  • 使用 => 来定义 , function(){} 等价于 () => {} ,代码变得更加简洁
  • 箭头函数内部没有 arguments
  • 箭头函数不能使用 new 关键字来实例化对象,function 函数也是一个对象,但是箭头函数不是
1
2
3
4
5
6
7
8
9
let add = function(a, b){
return a + b;
}

// 上下两者写法等价

let add = (a, b) => {
return a + b;
}

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
let node = {
type:'iden',
name:'foo'
}

let {type,name} = node;
console.log(type,name)


//剩余运算符 使用此法将其它属性展开到一个对象中存储
let {a,...res} = obj;
console.log(a,res);

// 默认值 a 的值 20 ,b 的值 30
let {a,b = 30} = {a:20};


//对数组的解构
let [a, b] = [1, 2, 3];
console.log(a,b)
//可嵌套
let [a, [b], c] = [1, [2], 3]

对象扩展

  • **Object.is()**: 比较两个值是否严格相等
1
2
3
4
console.log(NaN === NaN)
console.log(+0 === -0)
console.log(Object.is(NaN, NaN))
console.log(Object.is(+0, -0))
  • Object.assign()

    Object.assign(target, obj1, obj2...)方法用于对象的合并,将原对象(obj)的所有属性,复制到目标对象(target)

1
2
let obj = Object.assign({}, {a:1}, {b:2})
console.log(obj)

Symbol类型

  • 它表示的是独一无二的值
  • 最大的用途:用来定义对象的私有变量
  • 如果用 Symbol 定义的是对象中的变量,取值时一定要用 [变量名]
  • 如果用 Symbol 定义的是对象中的变量,该变量不能作为key,无法用 for 循环遍历
1
2
3
4
5
6
7
8
9
10
11
12
const name1 = Symbol('name')
const name2 = Symbol('name')

console.log(name1 === name2)


let s1 = Symbol('s1')

let person = {
[s1]: 'qwe'
}
console.log(person[s1])

Set和Map

Set 集合:表示无重回复值的有序列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//new
let set1 = new Set()

set1.add(1)
set1.add('1')
console.log(set1)
console.log(set1.size)
set1.delete('1')
console.log(set1.has('1'))
set1.add(2)
set1.add(3)
set1.add(4)
//遍历
for(let k of set1){
console.log(k)
}
//set去重
let set2 = new Set([1,2,3,3,3,4])
console.log(set2)
let arr = [...set2]
console.log(arr)

Map:键值对的有序列表,键和值是任意类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let map1 = new Map()
map1.set('name', '张三')
console.log(map1)
console.log(map1.get('name'))
map1.delete('name')
console.log(map1.has('name'))

map1.set(['a', [1, 2, 3]], 'asd')
console.log(map1)

//初始化
let map2 = new Map([['a', 1], ['b', 2]])
console.log(map2)

数组的扩展方法

  • Array.from()方法用于将伪数组转为真正的数组
1
2
3
4
5
6
7
8
9
10
11
12
function add(){
let arr1 = Array.from(arguments)
console.log(arr1)
}
add(1,2,3)

let lis = document.querySelectorAll('li')
let arr = Array.from(lis)
console.log(arr)

let arr2 = Array.from(lis, ele => ele.textContent)
console.log(arr2)
  • Array.of()方法用于将一组值,转换为数组
1
2
let arr3 = Array.of(1, 2, '3', [1, 2], {id:1})
console.log(arr3)
  • copyWithin(target, start = 0, end = this.length); 在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组

    target(必需):从该位置开始替换数据。如果为负值,表示倒数。

​ start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。

​ end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

​ 这三个参数都应该是数值,如果不是,会自动转为数值。

1
2
let arr4 = [1,2,3,8,9,10].copyWithin(0, 3)
console.log(arr4) // [8, 9, 10, 8, 9, 10]
  • find() 方法:找出第一个符合条件的数组成员,它的参数是一个回调函数。

  • findIndex() 方法:找出第一个符合条件的数组成员的索引

1
2
3
4
5
let num = [1,2,-10, 8, -1].find( n => n < 0)
console.log(num)

let numIndex = [1,2,-10, 8, -1].findIndex( n => n < 0)
console.log(numIndex)
  • ES6 提供三个新的方法——entries()keys()values()——用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是:

keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
let arr5 = [1, 2, 4, 7, 3]
console.log(arr5.keys())
for(let k of arr5.keys()){
console.log(k)
}

for(let v of arr5.values()){
console.log(v)
}

for(let [k, v] of arr5.entries()){
console.log(k, v)
}
  • includes() 返回一个布尔值,表示某个数组是否包含给定的值

    注意:以前的 indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,返回值是1或-1,所以要去比较是否不等于-1,表达起来不够直观

1
console.log(arr5.includes(5))

Iterator遍历器

  • 遍历器(Iterator)它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员),快捷的访问数据。
  • Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。
  • Iterator 的遍历过程是这样的。
  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。
  5. 每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含valuedone两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束
  • 原生具备 Iterator 接口的数据结构如下。
  1. Array
  2. Map
  3. Set
  4. String
  5. TypedArray
  6. 函数的 arguments 对象
  7. NodeList 对象
1
2
3
4
5
6
7
let items = ['one', 'two', 'three'];
//创建一个遍历器
let ite = items[Symbol.iterator]();
console.log(ite.next()) // { value: 'one', done: false }
console.log(ite.next()) // { value: 'two', done: false }
console.log(ite.next()) // { value: 'three', done: false }
console.log(ite.next()) // { value: undefined, done: true }

Generator函数(生成器)

  • Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回一个遍历器对象。而 Generator 函数也是遍历器生成函数,可以把 Generator 函数赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口,给不具备 Iterator 接口的数据结构(不自带Symbol.iterator方法)提供遍历操作。
  • 形式上,Generator 函数是一个普通函数,但是有两个特征(区别)。一是,function关键字与函数名之间有一个星号 * ;二是,函数体内部使用yield表达式

  • Generator 函数是分段执行的,只有调用next方法才会遍历下一个内部状态。yield是暂停执行标志,next()是恢复执行。当 next() 传入参数时,该参数就会被当作上一个 yield 表达式的返回值

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
function* fun(){
console.log('one')
yield 'one'
console.log('two')
yield 'two'

}

let fn = fun()
console.log(fn)
console.log(fn.next())
console.log(fn.next())
console.log(fn.next())

console.log("****************")

function* add(){
console.log('one ')
let x = yield 'one'
console.log('two ' + 'x:' + x)
let y = yield 'two'
console.log('add ' + 'y:' + y)
return x + y
}

let fn2 = add()
console.log(fn2.next())
console.log(fn2.next(10))
console.log(fn2.next(30))
  • 使用场景:为不具备 Iterator 接口的对象提供了遍历操作
  • 利用for...of循环,可以写出遍历任意对象(object)的方法。原生的 JavaScript 对象没有遍历接口(不具备 Symbol.iterator方法),无法使用for...of循环,通过 Generator 函数为它加上这个接口,即将 Generator 函数加到对象的Symbol.iterator属性上面,就可以用了。
  • 除了for...of循环以外,扩展运算符(...)、解构赋值和Array.from方法内部调用的,都是遍历器接口。这意味着,它们都可以将 Generator 函数返回的 Iterator 对象,作为参数。
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
let person = {
name: '张三',
age: 12,
address: 'China'
}

function* ObjectEntries(obj){
const propKeys = Object.keys(obj)
for(const propKey of propKeys){
yield [propKey, obj[propKey]]
}
}


for(let [k, v] of ObjectEntries(person)){
console.log(k, v)
}
console.log(...ObjectEntries(person))

console.log("************")

function* ObjectEntries2(){
const propKeys = Object.keys(this)
for(const propKey of propKeys){
yield [propKey, this[propKey]]
}
}
person[Symbol.iterator] = ObjectEntries2

for(let [k, v] of person){
console.log(`${k} ${v}`)
}

console.log(...person)
console.log({name, age, address} = person)
  • Generator 函数在加载页面的异步应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function* load(){
loadUI()
yield showData()
hideUI()
}

let iteload = load()
iteload.next()

function loadUI(){
console.log('加载loading...页面')
}

function showData(){
setTimeout(() => {
console.log('数据加载完成')
iteload.next()
}, 1000);
}

function hideUI(){
console.log('隐藏loading...页面')
}

Promise对象

  • 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果

  • Promise 是一个对象,Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。axios 的内部实现原理就是通过 Promise 实现的

  • Promise对象有以下两个特点:

  1. 对象的状态不受外界影响。有三种状态:pending(进行中)、fulfilled(成功)和rejected(失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果
  • Promise对象是一个构造函数,用来生成Promise实例,带有一个回调函数,回调函数的两个参数是 resolve(成功) 和 reject(失败),这两个参数他们也是函数。
  • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
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
//基本使用        
let pro = new Promise(function(resolved, rejected){
//执行异步操作
let res = {
code: 201,
data: {
name: 'asd'
},
error: '失败了'
}

setTimeout(() => {
if(res.code === 200){
resolved(res.data)
}else{
rejected(res.error)
}
}, 1000)
})

console.log(pro)
pro.then((val) => {
console.log(val)
}, (err) => {
console.log(err)
})
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
//封装的Promise
function timeOut(ms){
return new Promise(function(resolved, rejected){
//执行异步操作
let res = {
code: 200,
data: {
name: 'asd'
},
error: '失败了'
}

setTimeout(() => {
if(res.code === 200){
resolved(res.data)
}else{
rejected(res.error)
}
}, ms)
})
}

timeOut(2000).then((val) => {
console.log(val)
})

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
//使用Promise封装Ajax
const getJSON = function(url){
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.setRequestHeader('Accept', 'application/json')
xhr.send()
xhr.onreadystatechange = handler
function handler(){
if(this.readyState === 4){
if(this.status === 200){
resolve(this.response.HeWeather6)
}else{
reject(new Error(this.statusText))
}
}
}
})
}

let a = getJSON('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
.then((data) => {
console.log(data[0])
}).catch((err) => {
console.log(err)
})
  • 如果一个promise执行完后 返回的还是一个promise 实例(注意,不是原来那个Promise实例),会把这个promise 的执行结果,传递给下一次then中。因此可以采用链式写法,即then方法后面再调用另一个then方法。
  • catch(err=>{})方法等价于then(null,err=>{}),用于指定发生错误时的回调函数

  • resolve()方法将现有对象转换成Promise对象,该实例的状态为 fulfilled 成功

1
2
3
4
5
6
//resolve()  reject()
let p = Promise.resolve('foo')
console.log(p)
p.then((data) => {
console.log(data)
})
  • reject()方法和resolve()方法一样返回一个新的Promise实例,该实例的状态为 rejected(失败)
1
2
3
4
5
let p2 = Promise.reject(new Error('出错了'));
//等价于 let p2 = new Promise((resolve,reject)=>reject(new Error('出错了)));
p2.catch(err => {
console.log(err);
})
  • all(): all()方法提供了并行执行异步操作的能力,并且再所有异步操作执行完后才执行回调

    应用:一些游戏类的素材比较多,等待所有图片,静态资源都加载完成,才进行页面的初始化

1
2
3
4
5
6
7
8
9
10
11
12
//all()

let p1 = new Promise(resolve => resolve())
let p2 = new Promise(resolve => resolve())
let p3 = new Promise(resolve => resolve())

let p4 = Promise.all([p1, p2, p3])
p4.then(() => {

}).catch(() => {

})
  • Promise.all()接受一个promise对象的数组,待全部完成之后,统一执行success;

  • race(): 接受一个包含多个promise对象的数组,只要有一个完成,就执行success

    应用:当我们请求某个图片资源,会导致时间过长,给用户反馈

    用race给某个异步请求设置超时时间,并且在超时后执行相应的操作

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
//race()
function requestImg(ImgSrc){
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = function(){
resolve(img)
}
img.src = ImgSrc
})
}

function timeout(){
return new Promise((resolev, reject) => {
setTimeout(() => {
reject(new Error('请求图片失败'))
}, 3000)
})
}

Promise.race([requestImg(''), timeout()]).then((data) => {
console.log(data)
}).catch((err) => {
console.log(err)
}).done(() => {

})
  • done()finally()

async异步操作

async 函数,它就是 Generator 函数的语法糖

作用:使得异步操作更加方便

  • 凡是在前面添加了async的函数在执行后都会自动返回一个Promise对象
1
2
3
4
5
6
async function test() {

}

let result = test()
console.log(result) //即便代码里test函数什么都没返回,我们依然打出了Promise对象
  • await必须在async函数里使用,不能单独使用
  • await的作用之一就是获取后面Promise对象成功状态传递出来的参数传给 then 函数。
1
2
3
4
5
6
7
8
9
async function f() {
/*
** 如果 await 命令后面的不是一个Promise实例对象,
** await 命令会自动把await后面转为一个Promise实例对象
*/
return await 'hello async';
}
// 因为返回的是一个Promise实例对象,所以可以用链式编程
f().then(v => {console.log(v)}).catch(e => {console.log(e)});
  • 如果 async 函数中有多个 await , 那么 then 函数 会等待所有的 await 指令运行完才去执行
1
2
3
4
5
6
async function f(){
let s = await 'hello world'
let data = await s.split('');
return data;
}
f().then(v => {console.log(v)}).catch(e => {console.log(e)});
  • 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
async function f(){
await Promise.reject('出错了');
await Promise.resolve('hello');
}
f().then(v => {console.log(v)}).catch(e => {console.log(e)}); //输出 出错了


/*
** async函数f执行后,await后面的 Promise 对象会抛出一个错误对象,
** 变成了 reject 状态,catch方法的回调函数被调用
*/
async function f2() {
await new Promise(function (resolve, reject) {
// 抛出一个错误对象
throw new Error('出错了');
});
}

f2().then(v => console.log(v)).catch(e => console.log(e))
// Error:出错了

针对上诉遇到 reject状态,就中断执行的问题,可以通过 try…catch 代码块解决

1
2
3
4
5
6
7
8
9
10
11
async function f() {
try {
await Promise.reject('出错了');
} catch (error){

}
return await Promise.resolve('hello');
});
}

f2().then(v => console.log(v)).catch(e => console.log(e)) // 输出 hello

class的用法

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
// es5 
/*
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
return this.sayName;
}
let p = new Person('牛肉粉',18);
console.log(p);
*/

// es6
class Person {
// 实例化的时候会立即被调用
constructor(name, age){
this.name = name;
this.age = age;
}
//等同于Person.prototype = function sayName(){}
sayName(){
return this.name;
}
sayAge(){
return this.age;
}
}
// 小技巧:通过 Objec.assign() 方法(详见对象的扩展功能)一次性向类中添加多个方法
/*
Object.assign(Person.prototype, {
sayName(){
return this.name;
}
sayAge(){
return this.age;
}
})
*/

let p = new Person('牛肉粉',18);
console.log(p);
p.sayName();
p.sayAge();
  • 类的继承
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
class Animal {
// 实例化的时候会立即被调用
constructor(name, age){
this.name = name;
this.age = age;
}
sayName(){
return this.name;
}
sayAge(){
return this.age;
}
}

class Dog extends Animal{
constructor(name, age, color){
// 如果 子类 继承了 父类,且 子类 中写了构造器,则 子类 构造器的 super 必须要调用
super(name, age); // 等同于 Animal.call(this,name,age); 继承父类的属性
this.color = color;
}
// 子类自己的方法
sayColor(){
return `${this.name}${this.age}岁了,它的颜色是${this.color}`;
}
// 重写父类的方法
sayName(){
// super 相同于 Animal
return this.name + super.sayAge + this.color;
}
}

let d1 = new Dog('小黄', 28, 'red');
console.log(d1.sayAge()); // 调用继承父类的方法
console.log(d1.sayColor()); // 调用子类自己的方法
console.log(d1.sayName()); // 调用重写父类的方法

模块化

  • ES6 模块功能主要有两个命令构成:export 和 import
  • export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
  • 一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//module/index.js
export const name = '张三';
export const age = 18;
export const sayName = function() {
console.log(fristName);
}

//也可以这样
const name = '张三';
const age = 18;
const sayName = function() {
console.log(fristName);
}
export {name, age, sayName}
1
2
//main.js
import {name, age, sayName} from './modules/index.js';//解构赋值 {name, age, sayName}

使用export default命令为模块指定默认输出,在其它模块加载该模块时,import命令可以为该匿名函数指定任意名字

1
2
3
4
5
6
7
8
9
10
11
//export-default.js
export default function(){
console.log('foo');
}

//或者写成
function foo() {
console.log('foo');
}

export default foo;

如果想在一条import语句中,同时输入默认方法(default)和其他接口(非default),可以写成下面这样

1
2
3
4
5
6
7
8
//export-default.js
export default function(){
console.log('foo');
}

export function add(){
console.log('add')
}
1
2
3
4
5
6
import customName,{add} from 'export-default.js'

// 方式二 * 代表所有属性和方法 as 代表重命名
import * as f from 'export-default.js'
console.log(f); // 输出一个 模块, 里面保存了 export 传过来的所有属性和方法
console.log(f.default);

export default也可以用来输出类

1
2
3
4
5
6
// MyClass.js
export default class Person{ ... }

// main.js
import Person from 'MyClass';
let o = new Person();

数组方法

ES5

  • indexof(): 用于查找数组中是否存在某个值,如果存在则返回某个值的下标,否则返回-1
1
2
3
4
let list = [1, 2, 3];

console.log(list.indexOf(2)) // 1
console.log(list.indexOf("蛙人")) // -1
  • map():map是一个数组函数方法,接收三个参数,valueindexself,返回值是处理完的结果,返回新数组。
1
2
3
4
5
6
7
8
9
let list = [1, 2, 3];

const res = list.map((value, key, self) => {
console.log(value) // 1 2 3
console.log(key) // 0 1 2
console.log(self) // [1, 2, 3]
return value * 2
})
console.log(res)
  • foreach():用于遍历一个数组,接收三个参数,valueindexself,返回值为undefined
1
2
3
4
5
6
7
8
9
let list = [1, 2, 3];

const res = list.forEach((value, key, self) => {
console.log(value) // 1 2 3
console.log(key) // 0 1 2
console.log(self) // [1, 2, 3]
return 123
})
console.log(res) // undefined
  • splice(): 用于数组删除或替换内容,接收三个参数:
    • 第一个参数是,删除或添加的位置
    • 第二个参数是,要删除的几位,如果为0则不删除
    • 第三个参数是,向数组添加内容
1
2
3
4
5
6
7
8
9
10
let list = [1, 2, 3];

list.splice(0, 1) // 把第0个位置,给删除一位
console.log(list) // [2, 3]

list.splice(0, 1, "蛙人") // 把第0个位置,给删除一位,添加上一个字符串
console.log(list) // ["蛙人", 2, 3]

list.splice(0, 2, "蛙人") // 把第0个位置,给删除2位,添加上一个字符串
console.log(list) // ["蛙人", 3]
  • slice():用于截取数组值,接收两个参数,第一个参数是要获取哪个值的下标,第二个参数是截取到哪个下标的前一位。
1
2
3
4
let list = [1, 2, 3];

let res = list.slice(1, 3) // 从第一位下标开始截取,到第三位下标的前一位,所以截取出来就是 [2, 3]
console.log(res) // [2, 3]
  • filter():用于过滤数组内的符合条件的值,返回值为满足条件的数组对象
1
2
3
4
let list = [1, 2, 3];

let res = list.filter(item => item > 1);
console.log(res) // [2, 3]
  • every():用于检测数组所有元素是否都符合指定条件,返回值为Boolean , 该方法是数组中必须全部值元素满足条件返回true,否则false
1
2
3
4
5
6
7
let list = [1, 2, 3];

let res = list.every(item => item > 0)
console.log(res) // true

let res1 = list.every(item => item > 1)
console.log(res1) // false
  • some():用于检测数组中的元素是否满足指定条件,返回值为Boolean , 该方法是只要数组中有一项满足条件就返回true,否则false
1
2
3
4
let list = [1, 2, 3];

let res = list.some(item => item > 0)
console.log(res) // true
  • reduce(): 该方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。该方法回调函数接收四个参数

    • 第一个参数:初始值, 或者计算结束后的返回值
    • 第二个参数:当前元素
    • 第二个参数:当前元素的索引
    • 第四个参数:当前元素所属的数组对象,本身

    我们一般只用前两个就行,reduce第一个参数回调函数,第二个参数是初始值

1
>reduce(function(previousValue, currentValue, currentIndex, array) { /* … */ }, initialValue)

callbackFn

一个“reducer”函数,包含四个参数:

  • previousValue:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]
  • currentValue:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]
  • currentIndex:数组中正在处理的元素的索引。若指定了初始值 initialValue,则起始索引号为 0,否则从索引 1 起始。
  • array:用于遍历的数组。

initialValue 可选

作为第一次调用 callback 函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。

  • push() 向数组的末尾添加一个或更多元素,并返回新的长度。
  • unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
  • pop() 删除并返回数组的最后一个元素
  • shift() 删除并返回数组的第一个元素
  • reverse() 颠倒数组中元素的顺序。
  • join():用于数据以什么形式拼接
1
2
3
4
5
6
7
let list = [1, 2, 3];

let res = list.join("-");
console.log(res) // 1-2-3

let sum = eval(list.join("+"))
console.log(sum) // 6
  • sort():可之间排序,或使用回调函数,用于将数组排序,排序规则看返回值
1
2
3
4
let list = [1, 2, 3];

let sort = list.sort((a, b) => b - a)
console.log(sort) // [3, 2, 1]
  • concat(): 用于合并数组原始
1
2
3
4
let list = [1, 2, 3];

let res = list.concat([1, 2, 3])
console.log(res) // [1, 2, 3, 1, 2, 3]
  • Array.isArray():检测对象是不是一个数组
1
2
3
4
let list = [1, 2, 3];

let res = Array.isArray(list)
console.log(res) // true