Symbol
在js中,常见的数据类型有undefined null string number boolean object,而es6中,则新增了第七种数据类型symbol。
symbol会生成一个独一无二的值,为常量
let s1 = Symbol() let s2 = Symbol() console.log(s1 === s2) // false // 因为Symbol生成的是一个独一无二的值,为常量,一般是作为对象的属性 let obj = { [s1]:1, [s2]:2 } console.log(obj) // { [Symbol()]: 1, [Symbol()]: 2 }
Symbol.for与Symbol差不多,但是Symbol.for会生成一个唯一的标识
let s1 = Symbol.for('foo') let s2 = Symbol.for('foo') console.log(s1 === s2) // true // 也可以通过Symbol.keyFor把标识找出来 console.log(Symbol.keyFor(s1)) // foo
Array
Array的常用方法有from reduce map forEach findIndex find every some filter includes等等
用法也很简单,我主要讲一下from和reduce。
Array.from
把伪数组(包括不含有迭代器的伪数组)转化为数组
// 声明一个伪数组 let likeArr = { 0:1,1:2,2:3,length:3 } // 转换为数组 Array.from(likeArr) // [1,2,3]
那么我们用前面所说的扩展运算符,能够把伪数组转为数组吗?
// 声明一个伪数组 let likeArr = { 0:1,1:2,2:3,length:3 } // 用扩展运算符转换为数组 let arr = [...likeArr] // 报错 likeArr is not iterable
likeArr is not iterable意思是,likeArr这个伪数组没有迭代器,
那么可以看出,Array.from和...扩展运算符的区别了,
Array.from可以将伪数组(包含没有迭代器的伪数组)转为数组,
而...扩展运算符只能把拥有迭代器的伪数组转为数组,如arguments、map、set,
那么我们如果想用...扩展运算符转为数组,该怎么办呢?
// 既然扩展运算符只能把有迭代器的伪数组转为数组, // 那么我们就给伪数组添加一个迭代器 // 迭代器iterator需要一个generator生成器生成 // 我们给这个伪数组新增一个[Symbol.iterator]的迭代器 let likeArr = { 0:1,1:2,2:3,length:3,[Symbol.iterator]:function *() { for(let i = 0;i < this.length;i++){ yield this[i] } } } console.log([...likeArr]) // [1,2,3]
reduce
let arr = [1,2,3,4,5] // 参数一:前一个值 // 参数二:下一个值(当前值) // 参数三:当前的索引 // 参数四:arr数组 let total = arr.reduce(function(prev,next,currentIndex,arr){ return prev + next }) console.log(total) // 15 // 那么reduce是怎样一个运行流程呢? // 我们一步步拆解出来看 let arr = [1,2,3,4,5] // arr会一直是[1,2,3,4,5] // 第一步:此时的prev为1,next为2,currentIndex为1 let total = arr.reduce(function(prev,next,currentIndex,arr){ return prev + next // 1+2=3 并且把3当做下一次的prev }) // 第二步:此时的prev为3,next为3,currentIndex为2 let total = arr.reduce(function(prev,next,currentIndex,arr){ return prev + next // 3+3=6 并且把6当做下一次的prev }) // 第三步:此时的prev为6,next为4,currentIndex为3 let total = arr.reduce(function(prev,next,currentIndex,arr){ return prev + next // 6+4=10 并且把10当做下一次的prev }) // 第四步:此时的prev为10,next为5,currentIndex为4 let total = arr.reduce(function(prev,next,currentIndex,arr){ return prev + next // 10+5=15 最终结果会作为返回值返回 })
那我们自己实现一个reduce,看看是如何实现的
Array.prototype.myReduce = function (callback) { let prev = this[0] for(let i = 0;i < this.length-1;i++){ prev = callback(prev,this[i+1],i+1,this) } return prev } let arr = [1,2,3,4,5] let total = arr.myReduce(function(prev,next,currentIndex,arr){ console.log(prev,next) return prev + next }) console.log(total) // 15
map映射
可以把数组返回成一个映射后的数组
let arr = [1,2,3].map(item => item+1) console.log(arr) // [2,3,4]
find
查找,查找到后不再继续查找,查找不到则返回undefined,内部返回true的话,则返回当前item,
let arr = [1,2,3,4] let val = arr.find(item=>item === 3) console.log(val) // 3
every
每个值是否满足条件,如果是则返回true,如果不是则返回false
let arr = [1,2,3,4] let isTrue = arr.every(item => { return item > 0 }) console.log(isTrue) // true let isTrue2 = arr.every(item => { return item > 2 }) console.log(isTrue2) // false
some
是否有其中一个值满足条件,如果是则返回true,如果不是则返回false
let arr = [1,2,3,4] let isTrue = arr.every(item => { return item > 2 }) console.log(isTrue) // true let isTrue2 = arr.every(item => { return item > 4 }) console.log(isTrue2) // false
filter
过滤,在回调函数中返回的为false的话,相当于过滤掉当前项,返回一个过滤后的数组
let arr = [1,2,3,4] let newArr = arr.filter(item=>{ return item > 2 }) console.log(newArr) // [3,4]
includes
基本和some一样
Set
set是放不重复的项,也就是去重
let set = new Set([1,2,3,4,3,2,1]) console.log(set) // Set { 1, 2, 3, 4 }
Set有几个常用的方法,add clear delete entries
// add let set = new Set([1,2,3,4,3,2,1]) set.add(5) console.log(set) // Set { 1, 2, 3, 4, 5 } // 添加一个已有的值,则不会添加进去 set.add(1) console.log(set) // Set { 1, 2, 3, 4, 5 } // delete set.delete(3) console.log(set) // Set { 1, 2, 4, 5 } // entries console.log(set.entries()) // SetIterator { [ 1, 1 ], [ 2, 2 ], [ 4, 4 ], [ 5, 5 ] } // clear set.clear() console.log(set) // Set {}
Set常用于去重(并集)
function distinct(arr1,arr2){ return [...new Set([...arr1,...arr2])] } let arr = distinct([1,2,3],[2,3,4,5]) console.log(arr) // [1,2,3,4,5]
求交集
function intersect(arr1,arr2) { // 利用Set里的方法has,来判断new Set(arr2)中是否含有item, // 如果含有,那么则是true,当为true时,filter函数则会保留该项 // 如果没有,则是false,当为false时,filter函数则不会保留该项 return arr1.filter(item => new Set(arr2).has(item)) } console.log(intersect([1,2,3],[2,3,4,5])) // [2,3]
求差集
function difference(arr1,arr2){ return arr1.filter(item => !new Set(arr2).has(item)) } console.log(difference([1,2,3],[2,3,4,5])) // [1]