JS 数组、字符串 常用 API(持续更新)

一、Object.prototype.toString()

定义:

toString() 方法返回一个表示该对象的字符串。

语法:

obj.toString()

使用 toString() 检测对象类型

返回 [object type] 其中 type 是对象的类型

var o = new Object();
o.toString(); // [object Object]
var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

举例:

toString() 可以将数组转为字符串,但是我觉着 join(‘’) 更方便(因为没有逗号):

let o = {
  a: 1,
  b: 22
}
let arr = [2, 3, 4]

console.log(o.toString()) // [object Object]
console.log(arr.toString()) // 2,3,4
console.log(typeof arr.toString()) // string
console.log(arr.join()) // 2,3,4
console.log(arr.join('')) // 234

二、String.prototype.split()

MDN:
split() 方法使用指定的分隔符字符串将一个String对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。

理解:以规定分隔符将字符串分割为数组。

示例:

const str = 'In time to meet';

const words = str.split(' ')

console.log(words[2]) // to

const chars = str.split('')
console.log(chars[5]) // m

const strCopy = str.split()
console.log(strCopy)    // ['In time to meet']
console.log(strCopy[0]) // In time to meet

语法:

str.split(separator, limit)

参数:

  • separator:
    • separator 表示分隔符,可以是一个字符串或正则表达式。
    • 若 str 中未出现分隔符,则 返回一个包含整个 str 的数组。
    • 若分隔符为空字符串,则 返回 str 的字符组成的数组。
  • limit:
    • 一个整数,限定返回的分割片段数量。

示例:

const str = 'In time to meet';

const words = str.split(' ', 2) 

console.log(words) // ['In', 'time']

三、Array.prototype.reduce()

MDN:
reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

const array1 = [1, 2, 3];

// 0 + 1 + 2 + 3
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (previousValue, currentValue) => previousValue + currentValue, 
  initialValue // 初始值
);

console.log(sumWithInitial);  // 6

参数

  • 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 将使用数组第二个元素。

返回值:
使用 “reducer” 回调函数遍历整个数组后的结果。


例:

计算数组中每个元素出现的次数

let arr = ["a", "c", "c", "d", "a"];

let countArr = arr.reduce(function (preArr, char) {
  if (char in preArr) {
    preArr[char]++;
  } else {
    preArr[char] = 1;
  }
  return preArr;
}, {});

console.log(countArr); // {a: 2, c: 2, d: 1}

按属性值 分类

let people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

let groupBy = (array, property) => {
  // 因为 reduce 直接有返回值
  return array.reduce((pre, obj) => {
    let key = obj[property]  // key 是 obj 的属性值
    if (!pre[key]) {
      pre[key] = [] // 初始化数组
    }
    pre[key].push(obj)  // 将具有指定属性值相同的对象放在一个数组
    return pre
  }, {})
}

let groupedPeople = groupBy(people, 'age')
console.log(groupedPeople)
// groupedPeople is:
// {
//   20: [
//     { name: 'Max', age: 20 },
//     { name: 'Jane', age: 20 }
//   ],
//   21: [{ name: 'Alice', age: 21 }]
// }

数组去重

let arr = [3, 3, 4, 5, 5, 6, 6, 3, 1];
let deWeightArr = arr.reduce((pre, cur) => {
  if (pre.indexOf(cur) === -1) {
    pre.push(cur);
  }
  return pre;
}, []);
console.log(deWeightArr);

当然这样数组去重比较麻烦,在支持环境下可以用其他方法
如:

var a = Array.from(new Set([3,4,5,5,6,6,3]))
var a = [...new Set([3,4,5,5,6,6,3])]

使用 .reduce() 替换 .filter().map()

使用 Array.filter() 和 Array.map() 会遍历数组两次,而使用 Array.reduce() 只需遍历一次,更加高效。

// 将数组大于3的数乘10并组成数组返回
let arr = [1, 7, 3, 4, 6, 12];
let result= arr.reduce((pre, cur) => {
  if (cur > 3) {
    const mult = cur * 10
    pre.push(mult)
  }
  return pre;
}, []);
console.log(result);  // [70, 40, 60, 120]

示例参考:MDN Reduce


四、Array.prototype.map()

MDN:
map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

let arr = [1, 2, 3];
const mapArr = arr.map((x) => x * 10);
console.log(mapArr) // [10, 20, 30]

语法:

var newArr = arr.map(function callback(currentValue, index, array) {
}, thisArg)

参数:

  • callback。生成新数组元素的函数,有三个参数:
    • currentValue。正在处理的当前元素。
    • index 可选。正在处理的当前元素的索引。
    • array 可选。map 方法调用的数组。
  • thisArg 可选。执行 callback 函数时值被用作 this。

五、Array.prototype.unshift()

MDN:
unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。

let arr = [1, 2, 3]
console.log(arr.unshift(9, 7)) // 5
console.log(arr) // [9, 7, 1, 2, 3]

注:传入多个参数调用一次 unshift ,和传入一个参数调用多次 unshift ,将得到不同的结果。因为前者是将多个参数以块形式插入数组开始位置。而后者是一个一个插入数组开始位置。

六、Array.prototype.shift()

MDN:
shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

let arr = [2, 3, 4];
console.log(arr.shift()); // 2
console.log(arr); // [3, 4]

返回值:
从数组中删除的元素;如果该数组为空则返回 undefined

七、Array.prototype.forEach()

MDN:
forEach() 方法对数组的每个元素执行一次给定的函数。

let arr = [1, 2, 3];
arr.forEach(item => {
  console.log(item) // 1 2 3
})

语法:

arr.forEach(callback(currentValue, index, array), thisArg)

返回值:
undefined

八、for … of

MDN:
for...of 语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象、DOM 等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

无 for…of 之前,我们使用for 循环forEachfor...in 来遍历Array、Map、String。但这些方法有的却要转换、封装、侵入原型等,且方法不统一。
所以就出现了 ES6 的 for...of对不同数据结构进行统一遍历的方式是 ES6 的for...of

不是所有的对象都能使用 for…of,只有实现了 Iterator 接口的对象才能够使用 for...of 来进行遍历取值。所以 for…of 只是语法糖,真正的主角是Iterator
关于 Iterator 详细请看 https://juejin.cn/post/6844904025167495181

1、迭代 Array

let arr = [1, 2, 3]
for (let item of arr) {
  console.log(item)  // 1 2 3
}

2、迭代 String

let str = "hel"
for (let item of str) {
  console.log(item)  
}
// "h" 
// "e" 
// "l" 

3、迭代 Map

let map = new Map([[true, "a"], [3, 2]])

for (let item of map) {
  console.log(item)
}
// [true, 'a']
// [3, 2]

for (let [key, value] of map) {
  console.log(key, value)
}
// true 'a'
// 3 2

4、迭代 Set

let iterable = new Set([2, 3, 2, 2, 6])
for (let item of iterable) {
  console.log(item)
}
// 2
// 3
// 6

5、迭代 arguments 对象

(function() {
  for (let argument of arguments) {
    console.log(argument)
  }
})(1, 2, 3)
// 1
// 2
// 3

6、迭代 DOM 集合

    <div>
        <p>哈哈</p>
        <p>欧欧</p>
    </div>
    <p>嘿恩</p>
let elems = document.querySelectorAll("div > p")
for (let item of elems) {
  console.log(item.innerHTML)
}
// 哈哈
// 欧欧

7、关闭迭代器(即跳出循环)

let arr = [1, 3, 1, 6, 2];

for (var item of arr) {
  if (item > 3) break;
  console.log(item);
}
// 1
// 3
// 1

九、for … in

MDN:
for...in 语句以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。

for … in 是为遍历对象属性而构建的。

var obj = { a: 1, b: 2, c: 3 };

for (var prop in obj) {
  console.log(prop, obj[prop]);
}
// a 1
// b 2
// c 3

但是 for … in 会遍历 对象所有可枚举属性,包括自身的和继承的(原型链上的)属性
如下:

var obj = { a: 1, b: 2, c: 3 };

function Parent () {
  this.d = 10
}
Parent.prototype = obj

let child = new Parent()
for (var prop in child) {
  console.log(prop, child[prop]);
}
// d 10
// a 1
// b 2
// c 3

所以用到 hasOwnProperty() ,用 if 判断是属于自身属性,则打印

var obj = { a: 1, b: 2, c: 3 };

function Parent() {
  this.d = 10;
}
Parent.prototype = obj;

let child = new Parent();
for (var prop in child) {
  if (child.hasOwnProperty(prop)) {
    console.log(prop, child[prop]);
  }
}
// d 10

十、Array.prototype.slice()

MDN:
slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

let arr = [1, 2, 3, 4, 5];

console.log(arr.slice(2))     // [3, 4, 5]
console.log(arr.slice())      // [1, 2, 3, 4, 5]
console.log(arr.slice(2, 4))  // [3, 4]
console.log(arr.slice(-2))    // [4, 5]
console.log(arr.slice(1, -2)) // [2, 3]

//或者转换为数组
Array.prototype.slice.call(str);

类数组(Array-like)对象

slice 方法可以将一个类数组对象/集合转换成一个新数组。

let str = 'hello';
// 字符串转数组
let toArr1 = Array.prototype.slice.call(str)
console.log(toArr1) // ['h', 'e', 'l', 'l', 'o']

// arguments 转数组
function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

十、String.prototype.slice()

slice() 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。

let str = 'hello';

console.log(str.slice(2))     // "llo"
console.log(str.slice())      // "hello"
console.log(str.slice(2, 4))  // "ll"
console.log(str.slice(-2))    // "lo"
console.log(str.slice(1, -2)) // "el"

十一、Array.prototype.filter()

filter() 方法创建一个新数组,包含通过所提供函数实现的所有元素。(即起过滤作用,过滤掉不需要的,留下数组中需要的元素)
如果没有任何数组元素通过测试,则返回空数组。

let arr = [3, 7, 1, 2, 5];

let filterArr = arr.filter((item) => item < 3)
console.log(filterArr)  // [1, 2]

语法:
var newArray = arr.filter(callback(element, index, array), thisArg)
参数:
element:数组中当前正在处理的元素。
index(可选):正在处理的元素在数组中的索引。

十二、Array.prototype.concat()

MDN:
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

const arr1 = ['a', 'b', 'c'];
const arr2 = ['d', 'e', 'f'];
const arr3 = arr1.concat(arr2);

console.log(arr3);  // ['a', 'b', 'c', 'd', 'e', 'f']

concat 方法不会改变this或任何作为参数提供的数组,而是返回一个浅拷贝

十三、String.prototype.concat()

MDN:

concat() 方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。

性能:
强烈建议使用 赋值操作符(+, +=) 代替 concat 方法。

十四、Array.prototype.splice()

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

array.splice(start, deleteCount, item1, item2...)

参数:
start
deleteCount
item1

应用:
因为 vue 中 v-for 中值通过filter()、concat() 和 slice()改变,但并不重新渲染。而可以如下,使用 splice 等改变,v-for 可重新渲染。

let nextData = this.optionsData[index].filter(val => val.code == item.code)[0].children
this.optionsData.splice(index + 1, 1, nextData);

十五、Array.from

Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

console.log(Array.from('foo'));  // ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x * 2)) // [2, 4, 6]
Array.from(arrayLike, mapFn, thisArg)

参数:
arrayLike
要转换成数组 的伪数组对象 或 可迭代对象。

mapFn 可选
如果指定了该参数,新数组中的每个元素会执行该回调函数。

十六、Array.isArray()

MDN:
Array.isArray() 用于确定传递的值是否是一个 Array。

Array.isArray([1, 2, 3]);  // true

十七、String.prototype.match()

MDN:
match() 方法检索返回一个字符串匹配正则表达式的结果。

const regex = /a+/g
const found = 'ddda333aadd'.match(regex)
console.log(found)  // [ 'a', 'aa' ]

需注意 返回值
如果使用 g 标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。
如果未使用 g 标志,则仅返回第一个完整匹配及其相关的捕获组(Array)。返回的项目将具有 groups、index、input 属性。

const regex = /a+/
const found = 'ddda333aadd'.match(regex)
console.log(found)  
// [ 'a', index: 3, input: 'ddda333aadd', groups: undefined ]

十八、Array.prototype.every()

MDN:
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

语法:
every((element, index, array) => { } )

const arr = [1, 2, 3, 4]
const res = arr.every((val) => val < 10)
console.log(res) // true

十九、Array.prototype.find()

MDN:
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

const arr = [1, 2, 3, 4, 5, 6]
const res = arr.find((val, index) => val > 2 && index > 3)
console.log(res) // 5

二十、Array.prototype.findIndex()

MDN:
findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

const arr = [5, 2, 3, 7, 5, 6]
const res = arr.findIndex((val, index) => val > 2 && index > 3)
console.log(res) // 4

二十一、Array.prototype.includes()

MDN:
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。

语法:
arr.includes(valueToFind[, fromIndex])
valueToFind:需要查找的元素值。
fromIndex 可选:从fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜。默认为 0。
(使用 includes() 比较字符串和字符时是区分大小写的。)

const arr = ['a', 'b', 'c', 'd'];
console.log(arr.includes('b'));  // true
// 第二个参数设置从对应索引处开始查找
console.log(arr.includes('b', 2));  // false

二十二、Array.prototype.some()

MDN:
some() 方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。

const arr = [1, 2, 3, 4, 5, 6]
const res = arr.some((val) => val > 2)
console.log(res) // true

二十三、Array.prototype.fill()

MDN:
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

语法:

fill(value)
fill(value, start)
fill(value, start, end)

示例:

console.log([1, 2, 3].fill(6));   // [ 6, 6, 6 ]
console.log([2, 3, 2, 5].fill(6, 1));   // [ 2, 6, 6, 6]
console.log([22, 33, 25, 18].fill(6, 1, 3));   // [ 22, 6, 6, 18 ]
console.log(Array(3).fill(6));   // [ 6, 6, 6 ]

二十四、Array.prototype.reverse()

MDN:
reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

let arr = ['a', 'b', 'c', 'd']
let reversed = arr.reverse()
console.log(arr) // [ 'd', 'c', 'b', 'a' ]
console.log(reversed) // [ 'd', 'c', 'b', 'a' ]
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢莱

为您解决问题,此项目我成功完成

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值