Javascript方法整理

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])
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容