Array
Array.from()
Array.from()方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
//将Set结构的数据转换为真正的数组
console.log(Array.from(new Set([1,5,2,8,8,4])))//[1,5,2,8,4]
//将字符串转换为数组
console.log(Array.from('foo'))//["f", "o", "o"]
//接受第二个参数,作用类似于数组的map方法
console.log(Array.from([1, 2, 3], x => x + x))//[2, 4, 6]
Array.prototype.flat()
Array.flat()方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。换句话说,就是将嵌套的数组“拉平”(默认只会“拉平”一层),变成一维数组。该方法返回一个新数组,对原数据没有影响
var newArray = arr.flat([depth])
depth指定要提取嵌套数组的结构深度,默认值为 1。
//默认depth为 1
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());//[0, 1, 2, 3, 4]
//depth为 2
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));//[0, 1, 2, [3, 4]]
//使用 Infinity,可展开任意深度的嵌套数组
var arr3 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
console.log(arr3.flat(Infinity));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//flat() 方法会移除数组中的空项
var arr4 = [1, 2, , 4, 5];
console.log(arr4.flat());//[1, 2, 4, 5]
补充:flatMap()方法对原数组的每个成员执行一个函数,相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。
// 只能展开一层数组。相当于 [[2, 4], [3, 6], [4, 8]].flat()
console.log([2, 3, 4].flatMap((x) => [x, x * 2]));// [2, 4, 3, 6, 4, 8]
将二维数组转化为一维的其他方法
//reduce方法
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
//将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
Array.prototype.sort()
Array.sort()对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
console.log(['March', 'Jan', 'Feb', 'Dec'].sort());//["Dec", "Feb", "Jan", "March"]
console.log([1, 3, 1000,'a', 'Dec','A'].sort());//[1, 1000, 3, "A", "Dec", "a"]
//一个数组按照另一个数组排序
let arr = [{id:5},{id:8},{id:4},{id:1},{id:6}]
let arr2 = [1,2,3,4,5,6,7,8]
let arr3 = arr.sort((a,b)=>{
return arr2.indexOf(a.id) - arr2.indexOf(b.id)
})
console.log(arr3)// [{id: 1}, {id: 4}, {id: 5}, {id: 6}, {id: 8}]
Array.prototype.filter()
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 filter把传入的函数依次作用于每个元素,然后根据返回值是 true 还是false决定保留还是丢弃该元素
//去重
let arr = [1,4,6,3,6,8,9,1];
let newarr = arr.filter((item,index,array) => {
return array.indexOf(item) === index
})
console.log(newarr);// [1,4,6,3,8,9]
//筛选出不同元素
let arr = [{id:5},{id:8},{id:4},{id:1},{id:6}]
let arr2 = [{id:1},{id:2},{id:3},{id:4},{id:5}]
let arr3 = arr.filter(x=> arr2.every(y=>x.id !== y.id))
console.log(arr3)//[{id: 8},{id: 6}]
去重其他方法
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
//利用set
console.log([...new Set(arr)])//[1,2,3,4]
Array.prototype.every()
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
let arr = ['apple','banana','orange','pear','watermelon'];
let every = arr.every((item,index,array) => {
return item.length>10
})
console.log(every);//false
Array.prototype.some()
some() 方法与every() 方法相反,some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
let arr = [1,2,3,4,5];
let someResult = arr.some((item,index,arr) => item%2==0);
console.log(someResult); //true
Array.prototype.forEach()和Array.prototype.map()
forEach()方法对数组的每个元素执行一次给定的函数。
map()方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
区别:forEach()方法不会返回执行结果,而是undefined。也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。
//forEach
let arr = [1,2,3,4,5];
arr.forEach((item,index,array) => {
arr[index] = item + 1;
})
console.log(arr)//[ 2, 3, 4, 5, 6 ]
//map
let arr = [1,2,3,4,5];
let arr2 = arr.map((item,index,arr) => item*2)
console.log(arr2)//[ 2, 3, 4, 5, 6 ]
Array.prototype.reduce()
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
第一个参数callback函数: pre为上次return的值,next为数组的本次遍历的项
第二个参数为初始值,也是第一个pre
let arr = [1,2,3,4,5];
let sum = arr.reduce((pre,next) => {
console.log(pre,next)//0,1 1,2 3,3 6,4 10,5
return pre + next
},0)
console.log(sum) //15
//若initialValue 为 1
let sum = arr.reduce((pre,next) => {
console.log(pre,next)//1,1 2,2 4,3 7,4 11,5
return pre + next
},1)
console.log(sum) //16
//引申 pipe
const pipe = ...args => x =>
args.reduce(
(outputValue, currentFunction) => currentFunction(outputValue),
x
)
//示例
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const f1 = x => {
return x+1;
}
const f2 = x => {
return 2 * x;
}
// (1+1)*2 = 4
let result = pipe(f1, f2)(1);
console.log(result);
Array.prototype.includes()
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));// true
跟indexOf很像,但还是有区别的
const arr = [1,2,3,4,5,NaN]
console.log(arr.includes(NaN))//true
console.log(arr.indexOf(NaN))//-1
ES6数组:两个数组或数组对象取并集、交集、差集
https://www.jianshu.com/p/20523688cbee
Object
Object .entries(),Object .keys()和Object .values()
都返回一个由一个给定对象的自身可枚举属性的数组。唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
补充: Object.fromEntries() 方法把键值对列表转换为一个对象。
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
console.log(Object.keys(obj))// ['foo', 'bar']
console.log(Object. values(obj))// ['baz', 42]
const entries = new Map([
['foo', 'bar'],
['baz', 42]
]);
const obj = Object.fromEntries(entries);
console.log(obj);// expected output: Object { foo: "bar", baz: 42 }
// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}
// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
//将Object转化为Map
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
Object.entries("foo");//[["0", "f"],["1", "o"],["2", "o"]]
//在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015(ES6)中,非对象的参数将被强制转换为一个对象
Object.keys("foo");// TypeError: "foo" is not an object (ES5 code)
Object.keys("foo");// ["0", "1", "2"] (ES2015 code)
console.log(Object.values('foo')); // ['f', 'o', 'o']
其他
for..of..和for...in...
for in :以任意顺序遍历一个对象的除Symbol以外的可枚举属性。为遍历对象属性而构建的,不建议与数组一起使用,数组可以用。
for of :在可迭代对象包括Array,Map,Set,String,TypedArray,arguments 对象等等上创建一个迭代循环。
const obj = {name: 'amy', age: 18, gender: 'man'}
const arr = [1,2,3,4,5]
for (let key in obj){
console.log(key)//name age gender
}
for (let index in arr){
console.log(index)//0 1 2 3 4
}
for (let item of arr){
console.log(item)//1 2 3 4 5
}
async/await
以同步方式执行异步操作。
场景:接口一,请求到数据一,而数据一被当做请求二的参数去请求数据二。用promise会嵌套多层,美观及可读性较差,可以用async/await,但要注意以下几点:
-await只能在async函数里使用
-await后面最好接Promise,如果后面接的是普通函数则会直接执行
-async函数返回的是一个Promise
function fn1(){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('fn1success')
},1000)
})
}
function fn2(data){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('fn2success,'+data)
},2000)
})
}
async function req() {
const data1 = await fn1()//等待1s后返回数据再往下执行
const data2 = await fn2(data1)//拿fn1的返回值去请求fn2,2s后返回数据
console.log(data2)//共3s后输出 fn2success,fn1success
}
req()
String.trimStart && String.trimEnd
trim方法,可以清除字符串首尾的空格,trimStart和trimEnd用来单独去除字符串的首和尾的空格
const str = ' 哈哈哈 '
console.log(str.trim())//哈哈哈
console.log(str.trimStart())//哈哈哈
console.log(str.trimEnd())// 哈哈哈
?. 和 ?? (ES11)
?.为可选链
//比如我们需要一个变量,是数组且有长度,才做某些操作
const list = null
// do something
if (list && list.length) {
// do something
}
// 使用可选链
const list = null
// do something
if (list?.length) {
// do something
}
//比如有一个对象,我要取一个可能不存在的值,甚至我们都不确定obj是否存在
const obj = {
cat: {
name: '哈哈'
}
}
const dog = obj && obj.dog && obj.dog.name // undefined
// 可选链
const obj = {
cat: {
name: '哈哈'
}
}
const dog = obj?.dog?.name // undefined
//数组取索引为1的值
const item = arr?.[1]
??为空位合并运算符
使用||运算符,只要左边是假值,就会返回右边的数据
const str = '哈哈哈'
console.log('' || str)//哈哈哈
console.log(0 || str)//哈哈哈
console.log(null || str)//哈哈哈
console.log(undefined || str)//哈哈哈
console.log(false || str)//哈哈哈
而??和||最大的区别是,在??这,只有undefined和null才算假值
console.log('' ?? str)//''
console.log(0 ?? str)//0
console.log(null ?? str)//哈哈哈
console.log(undefined ?? str)//哈哈哈
console.log(false ?? str)//false
数组和对象相互转换
export const arrToObj = (arr) =>{
return arr.reduce((prev,current)=>{
if (current._id){
prev[current._id] = current
}
return prev
},{})
}
export const objToArr =(obj) =>{
return Object.keys(obj).map(key=>obj[key])
}
扩展 用ts定义
interface TestProps {
_id: string;
name: string;
}
const testData: TestProps[] = [{ _id: '1', name: 'a' }, { _id: '2', name: 'b' }]
const testData2:{[key:string]:TestProps} ={
1:{_id: '1', name: 'a'},
2:{ _id: '2', name: 'b' }
}
export const arrToObj = <T extends {_id?:string}>(arr:Array<T>) =>{
return arr.reduce((prev,current)=>{
if (current._id){
prev[current._id] = current
}
return prev
},{} as {[key:string]:T})
}
export const objToArr = <T>(obj:{[key:string]:T}) =>{
return Object.keys(obj).map(key=>obj[key])
}