数组方法在JS中是一个重要的知识点。本文将重点讲解一些方法的使用细节和使用场景。以下是对数组方法的分类
方法 | 说明 |
---|---|
Array.from() | 从数组类对象或可迭代对象创建一个新的 Array 实例。 |
Array.isArray() | 如果参数是数组则返回 true ,否则返回 false 。 |
应用场景:Array.from()这个方法常用于转化NodeList类数组对象,让dom集合也能拥有数组方法。
方法 | 说明 |
---|---|
Array.prototype.pop() | 从数组中移除最后一个元素并返回该元素。 |
Array.prototype.push() | 在数组末尾添加一个或多个元素,并返回数组新的 length。 |
Array.prototype.shift() | 从数组中移除第一个元素并返回该元素。 |
Array.prototype.unshift() | 在数组的前面添加一个或多个元素,并返回数组新的 length。 |
应用场景:我们可以利用上述方法能够非常简单的模拟栈和队列这两种数据结构,如下:
let arr = [ 1, 2, 3, 4, 5 ]
// 栈数据结构,后进先出。
arr.pop(5) // 出栈操作 [ 1, 2, 3, 4 ]
arr.push(5) // 入栈操作 [ 1, 2, 3, 4, 5 ]
// 队列数据结构,先进先出。
arr.shift(1) // 出队操作 [ 2, 3, 4, 5 ]
arr.push(1) // 入队操作 [ 1, 2, 3, 4, 5 ]
其中pop和push方法分别对应栈的出栈与入栈操作。shift和push方法分别对应队列的出队和入队操作。
当然,我们也可以进一步基于以上方法利用面向对象编程分别封装栈和队列这样的数据结构进行操作。
方法 | 说明 |
---|---|
Array.prototype.forEach() | 对调用数组中的每个元素调用函数。 |
Array.prototype.map() | 返回一个新数组,其中包含对调用数组中的每个元素调用函数的结果。 |
应用场景:以上两个方法都十分常用。其中NodeList自带forEach方法,在DOM编程中可以应用。 此外,在vue中我们常常会设计这样一个数据结构用于v-for循环。
let arr = [
{ id: 0, name: "小红", age: 22 },
{ id: 1, name: "小华", age: 18 },
{ id: 2, name: "小明", age: 24 },
]
arr.forEach((element) => {
console.log(element.name) // 结果:"小红" "小明" "小华"
})
let result = arr.map((element) => { // 方法返回一个新数组,我们使用result变量接收
return element.id * 2 // 返回的element会作为result数组中的元素
})
console.log(result) // 结果:[ 0, 2, 4 ]
使用以上方法可以非常简便的访问数组中每个对象的属性,以此对每个对象属性值进行统计、运算和赋值等操作。
方法 | 说明 |
---|---|
Array.prototype.find() | 返回数组中满足提供的测试函数的第一个元素的值,如果没有找到合适的元素,则返回 undefined。 |
Array.prototype.findIndex() | 返回数组中满足提供的测试函数的第一个元素的索引,如果没有找到合适的元素,则返回 -1。 |
Array.prototype.indexOf() | 返回在调用数组中可以找到给定元素的第一个(最小)索引。 |
应用场景:需要根据条件获取索引或值的元素。一般根据返回值用于判断数组内是否存在符合条件的元素。
方法 | 说明 |
---|---|
Array.prototype.includes() | 确定调用数组是否包含一个值,根据情况返回 true 或 false。 |
Array.prototype.some() | 如果调用数组中至少有一个元素满足提供的测试函数,则返回 true。 |
Array.prototype.every() | 如果调用数组中的每个元素都满足测试函数,则返回 true。 |
Array.prototype.filter() | 返回一个新数组,其中包含调用所提供的筛选函数返回为 true 的所有数组元素。 |
Array.prototype.reduce() | 对数组的每个元素(从左到右)执行用户提供的 “reducer” 回调函数,将其简化为单个值。 |
应用场景:这里重点讲解filter和reduce两个最常用的方法。
reduce((previousValue, currentValue) => { /* … */ } , initialValue)
其中reduce方法接收两个参数:一个是回调函数,一个是初始值。若已设定初始值initialValue,回调函数中的第一个参数previousValue等于initialValue,第二个参数为数组的第一个元素。在reduce方法遍历过程中,回调函数的第二个参数currentValue将会按顺序访问数组元素。第一个参数previousValue则为上一次return的结果。来看一个数组去重的应用例子:
let a = [1, 2, 2, 3, 3, 3]
function unique(arr) {
return arr.reduce((pre, cur) => {
return pre.includes(cur) === true ? pre : pre.concat(cur) // concat会返回一个新数组
// 判断上一次return的结果(pre)是否存在相同元素。
// 如果存在pre不变直接return返回;若不存在pre合并当前元素后return返回
}, []) // [] 空数组作为初始值
}
console.log(unique(a)) // 结果:[ 1,2,3 ]
let arr = [
{ id: 0, name: "小红", age: 22 },
{ id: 1, name: "小华", age: 18 },
{ id: 2, name: "小明", age: 24 },
]
// 这里做一个筛选,我们只要大于18岁的人作为新数组数据
// 使用filter方法
let filterResult = arr.filter(element => element.age > 18) // 不用花括号会直接return表达式
console.log(filterResult)
// 结果:[{ id: 0, name: "小红", age: 22 }, { id: 2, name: "小明", age: 24 }]
// 使用map方法
let mapResult = arr.map(element => element.age > 18) // 不用花括号会直接return表达式
console.log(mapResult)
// 结果:[ true, false, true ]
这里做一个比较:filter相比map的区别。当数组内元素的不符合条件时,map方法内部不符合条件的元素仍然会根据return的内容占据原来的位置;而filter方法则根据return的条件(true或false)去掉不符合的元素,返回符合条件元素组成的数组。
方法 | 说明 |
---|---|
Array.prototype.join() | 将数组的所有元素连接为字符串。 |
Array.prototype.concat() | 返回一个新数组,该数组由被调用的数组与其它数组或值连接形成。 |
说明:concat方法可以进行数组合并。如下:
let arr = [].concat([1, 2], [3, 4])
console.log(arr)
// 输出结果:[1, 2, 3, 4]
值得注意的点:
concat方法不会改变数组,而是返回一个新数组,需要使用变量接收这个新数组。
concat方法传入的参数如果是嵌套数组会展开其第一层进行合并。如下:
let arr = [].concat(1, 2, [3, 4, [5, 6, [7, 8]]])
console.log(arr)
// 输出结果:[1, 2, 3, 4, Array(3)]
应用场景:我们利用上面concat方法传入参数是嵌套数组会展开一层进行合并的特点,再加上扩展运算符和递归的思想可以非常巧妙的实现数组扁平化。如下:
// 三行代码实现数组扁平化
function flatten(arr, deep) {
return deep > 0 ? flatten([].concat(...arr), deep - 1) : arr
}
// 参数说明:arr = 原数组,deep = 展开的深度(从0开始,完全展开可以设为Infinity)
let a = [1, 2, [3, 4, [5, 6, [7, 8]]]] // 原数组
let result = flatten(a, 3) // 传入数组执行方法,展开深度为3
console.log(result)
// 输出结果:[1, 2, 3, 4, 5, 6, 7, 8]
过程分析如下:
原始数组:[1, 2, [3, 4, [5, 6, [7, 8]]]]
扩展运算符将原始数组展开后:1, 2, [3, 4, [5, 6, [7, 8]]]
concat方法的传入参数合并后:[1, 2, 3, 4, [5, 6, [7, 8]]]
重复上面的展开与合并过程,可以深度拍平数组。
方法 | 说明 |
---|---|
Array.prototype.slice() | 提取调用数组的一部分并返回一个新数组。 |
Array.prototype.splice() | 从数组中添加和/或删除元素。 |
说明:我们重点关注slice和splice的参数说明。如下:
let a = [1, 2, 3, 4, 5, 6]
let b = a.slice(2, 4) // 提取位置2到位置4的元素,返回一个新数组用变量b接收
console.log(b) // [3, 4]
参数说明:slice(start, end)方法可接收两个参数,一般用于提取数组中的元素。
start是数组开始提取的位置,若是负值则代表倒数第几位开始(等价array.length - n),若start超出数组长度则会返回空数组。
end代表数组终止提取的位置,若end被省略或end超出数组长度slice()方法都会从start开始提取到数组末尾。
slice() 会提取原数组中索引从 begin 到 end 的所有元素(包含 begin,但不包含 end)作为新数组返回。
let a = [1, 2, 3, 4, 5, 6]
a.splice(2, 4, 7) // 从位置2开始删除4个元素,删除后在原数组位置2添加元素7
console.log(a) // [1,2, 7]
参数说明:splice(start, deleteCount, item1, item2, itemN)方法可接收三个以上参数,可用于删除数组中的元素,
start:代表数组开始修改的位置,若是负值则代表倒数第几位开始(等价array.length - n),若start超出数组长度则以末尾开始修改。
deleteCount:代表从start开始要移除的元素个数(含第 start 位), 若deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除。
item1,item2...:代表删除后从原数组start位置开始要添加的数据,会在删除后不指定则 splice() 方法只会删除数组元素。
方法 | 说明 |
---|---|
Array.prototype.sort() | 对数组的元素进行排序并返回该数组。 |
Array.prototype.reverse() | 反转数组中元素的顺序。 |
sort方法利用原地算法对数组进行排序。简单来说就是在不开阔新的空间情况下,只能在原数组内用相互替换的方法交换数组内元素进行排序。比如冒泡排序、插入排序和希尔排序等空间复杂度为O(log n)的排序算法。当然我们最关心的还是它的用法。sort方法接收一个回调函数fn,回调函数里可以传入两个参数a和b。排序过程中回调函数的返回值可以有以下情况:
fn(a, b) > 0:a在b之后
fn(a, b) < 0:a在b之前
fn(a, b) === 0:a和b位置保持不变
let strs = ['Axios', 'Candy', 'Mike', 'Alice']
let a = strs.sort()// 没有回调函数,默认按元素转化成后字符串的各个字符的Unicode代码点进行排序
console.log(a) // ['Alice', 'Axios', 'Candy', 'Mike']
// 字母相同的元素('Axios'和'Alice')会利用元素下一个字符串的Unicode代码点继续进行排序
let nums = [2, 1, 4, 3, 5, 6]
let b = nums.sort((a, b) => a - b) // 存在回调函数,a-b为升序
console.log(b)
let c = nums.sort((a, b) => b - a) // 存在回调函数,b-a为降序
console.log(c)
let objs = [
{ id: 0, name: "小红", age: 22 },
{ id: 1, name: "小华", age: 18 },
{ id: 2, name: "小明", age: 24 },
]
let d = objs.sort((a, b) => a.age - b.age) // 也可以利用对象属性值进行排序(这里是升序)
console.log(d) // 按年龄大小对元素排序
reverse()方法用于数组逆序,如下:
let nums = [1, 2, 3, 4, 5, 6]
nums.reverse()
console.log(nums) // [6, 5, 4, 3, 2, 1]
特别注意:所有返回新数组的数组方法都不会改变原有数组,因此要用一个新变量接收返回的新数组。
返回新数组的方法总结如下:
在网络上我们每天都需要利用字符进行交流,间接说明我们应该掌握字符串的处理方式。这是前端开发中不可或缺的技能。以下是字符串方法的分类:
方法 | 说明 |
---|---|
String.prototype.indexOf() | 并返回指定子字符串第一次出现的索引。 |
String.prototype.match() | 用于将正则表达式 regexp 与字符串匹配。 |
String.prototype.search() | 搜索正则表达式 regexp 和调用字符串之间的匹配项。 |
我们重点关注一下indexOf方法。indexOf方法可以搜索子字符串第一次出现的索引。根据传入参数的不同搜索的结果分别以下有三种情况:
let a = "abc";
a.indexOf("c") // 正确传参,输出结果:2
a.indexOf() // 不传参数,输出结果:"undefined"
a.indexOf("d") // 传入参数错误或子字符串在字符串中找不到,输出结果:-1
match方法传入一个正则表达式作为参数,与search方法的区别是:match方法会返回结果分为两种情况:若正则表达式设为全局匹配g会返回一个匹配的子字符串结果(数组形式),若未设定全局匹配则会返回一个有特定结构的结果数组。如果都没匹配成功则返回null。search方法则会返回首次匹配字符串的索引,不匹配返回-1。
let a = "AbCdEfG"
let regex1 = /[A-Z]/g // 设定全局匹配
a.match(regex1) // 输出结果:['A', 'C', 'E', 'G']
let regex2 = /[A-Z]/ // 为设定全局匹配
a.match(regex2) // 输出结果:['A', index: 0, input: 'AbCdEfG', groups: undefined]
方法 | 说明 |
---|---|
String.prototype.replace() | 用于使用 replaceWith 替换出现的 searchFor。 |
应用场景:可以做字符替换,replace方法接收两个参数。第一个参数可以是正则表达式或字符串,第二个参数是要替换的内容。replace方法在字符串匹配成功后,会进行替换。替换如下:
let str = 'My name is Jelly';
str.replace('Jelly', 'Mary') // 输出结果: 'My name is Mary'
方法 | 方法 |
---|---|
String.prototype.concat() | 合并两个(或更多)字符串的文本并返回一个新字符串。 |
字符串的concat方法跟数组的concat方法操作基本相同。用于字符串的合并操作。
方法 | 说明 |
---|---|
String.prototype.trim() | 修剪字符串开头和结尾的空格。 |
String.prototype.trimStart() | 修剪字符串开头的空格。 |
String.prototype.trimEnd() | 修剪字符串结尾的空格。 |
应用场景:去掉字符串的首尾空格,如下:
let str = ' Hello, World ';
str.trim(); // 输出结果:'Hello, World'
方法 | 说明 |
---|---|
String.prototype.toLowerCase() | 字符串中的字符将转换为小写。 |
String.prototype.toUpperCase() | 字符串中的字符将转换为大写。 |
应用场景:以上的字符串方法可以应用于字母的大小写替换,可以来做一道题。实现小驼峰式命名法:将一个英语短语转换为小驼峰式命名。例如:first name => firstName
function toConvertCase(str) {
let result = '' // 存储新字符串,用于合并新的字符
let count = 0 // 记录初始状态,因为第一个字母需要小写
let space = false // 记录字符状态,是否出现已经特殊字符
for (let i = 0; i < str.length; i++) {
if (str[i].search(/^[A-Za-z]+$/) === 0) {
if (count === 0 && space === false) {
count++
} // 此时count恒等于1,根据下面的三元表达式第一次出现的字母为小写
result = space === true && count !== 0
? result.concat(str[i].toUpperCase())
: result.concat(str[i].toLowerCase())
space = false // 第一次出现的字母和首字母大写后的字母都为小写,设为false
} else {
space = true
// 出现特殊字符space设为true。下一次若是字母则三元表达式的值为true,新字符串合并首字母大写。
}
}
return result
}
// 短语输入测试
let a = toConvertCase('!@# fiRst %^&*( nAmE !@#$ ')
let b = toConvertCase('423432 SEcOnd@3423423 NaME')
let c = toConvertCase('@ThIrd-3NAmE')
console.log(a) // 输出结果:firstName
console.log(b) // 输出结果:secondName
console.log(c) // 输出结果:thirdName
只要输入有特殊字符间隔的短语就能返回小驼峰式命名,容错率还是非常高的。获取的字符串特征如下:
可以根据上面的字符串特征进行解题,不过上面的使用好像有点超纲了。我们还是重点关注它怎么用就行了。
方法 | 说明 |
---|---|
String.prototype.slice() | 提取字符串的一部分并返回一个新字符串。 |
String.prototype.substring() | 返回一个新字符串,其中包含来自(或之间)指定索引(或多个索引)的调用字符串的字符。 |
字符串的slice方法跟数组的slice方法操作基本相同。接收两个参数为开始和结束位置(不包括)进行字符提取。我们重点关注substring方法,这个是最常用的字符串截取操作。substring方法接收两个参数,这里暂且设为start和end两个参数,分别代表开始和结束位置(不包括)的字符。使用规则如下:
let a = "abcdefg"
a.substring(2, 2) // 输出结果:''
a.substring(2) // 输出结果:'cdefg'
a.substring(2, NaN) // 输出结果:'ab'
a.substring(8, 2) // 输出结果:'cdefg'
a.substring(4, 2) // 输出结果:'cd'
我们先温习一下JavaScript基础知识。在JavaScript中,根据+左右两边变量的类型的不同,+符号可以用于数字相加或则字符串拼接。我用了string += +string这样的写法,也就是说:由于写代码的时候拷贝黏贴,不小心整了一个多余的+号?
在我们使用JavaScript编写脚本的时候,经常会遇到把字符串两边的空格进行清除,它不想其它语言会有内置方法函数处理,js需要我们自己代码来实现。如果用过jquery库的话,它提供了trim方法,我们可以直接使用。
我们都知道prototype可以向对象上添加属性和方法,语法如下:object.prototype.name=value。这篇文章就是利用prototype,为字符串扩展过滤空格的方法
在开发中过程中,经常会遇到使用占位符的形式来格式化字符串,我们通过js扩展String.prototype.format字符串拼接的功能,实现如下:
es6中新增的字符串方法:字符串模板用法${变量名}、字符串查找方法string.includes(要找得字符串)、检查字符串是否已xxx开头、字符串重复方法string.repeat(次数)、字符串填充string.padStart
众所周知,js提供了很多字符串截取的方式。下面主要介绍js中slice(),splice(),split(),substring(),substr()的使用和区别,主要介绍了JavaScript截取、切割字符串的技巧,需要的朋友可以参考
看到一个题目要求写一个函数times,输出str重复num次的字符串。除了利用循环还有几种方法:递归,结合三元表达式更简洁。数组的 join() 方法。ES6的 repeat() 方法。ES6目前没有全部兼容。
对于常用的字符串原型的举例:在字符串末尾追加字符串 、删除指定索引位置的字符,索引无效将不删除任何字符 、删除指定索引区间的字符串 、检查字符串是否以subStr结尾
javascript提供stringA.localeCompare(stringB)方法,来判断一个字符串stringB是否排在stringA的前面。返回值: 如果引用字符存在于比较字符之前则为负数; 如果引用字符存在于比较字符之后则为正数; 相等的时候返回 0 。
ES6的includes, 返回 Boolean、ES5 indexOf,返回子串起始位置,不包含则返回-1、search,返回起始位置或者-1、lodash includes, JavaScript 工具库
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!