JavaScript数组方法总结及手写
文章首发:CSDN
手写数组衍生方法
1.检测是否为数组
<script>
var arr = [1,2,3]
//判断arr是否为数组,返回布尔值true 或false
//法一:Array.isArray()
console.log(Array.isArray(arr));
//法二:instanceof
console.log( arr instanceof Array);
//法三:判断arr的构造函数constructor有无包含Array
console.log(arr.constructor.toString().indexOf('Array')>-1);
//arr.constructor为ƒ Array() { [native code] }
//法四:用isPrototypeOf判断arr是否存在于Array的原型链中
console.log(Array.prototype.isPrototypeOf(arr));
/*
法五:万能判断变量类型方法Object.prototype.toString.call()
会返回一个形如 "[object XXX]" 的字符串
*/
console.log(Object.prototype.toString.call(arr).indexOf('Array')>-1);
//即console.log(Object.prototype.toString([])===Object.prototype.toString(arr));
</script>
2.类数组转化为数组
类数组对象,就是含有 length 属性且不是数组的对象,但结构表现上很像一个数组。
类数组对象主要有:
- 普通函数中的
argument
- 一些获取 Dom 集合的方法,如
document.querySelectorAll()、 document.getElementsByClassName、document.getElementsByTagName()
等也会返回类数组对象
<body>
<div>1</div>
<div>2</div>
<script>
let arg = document.querySelectorAll('div');
console.log(arg); //NodeList(2)
//法一: 用Array.from
console.log(Array.from(arg)); //Array(2)
//法二 :扩展运算符
console.log([...arg]);
//法三:用Array.prototype.slice.call():可将具有length属性的对象转成数组,因为slice方法返回一个新数组
console.log( Array.prototype.slice.call(arg));
//slice方法如果不传参数的话会返回原数组的一个拷贝,通过call显式绑定来实现使arguments也能调用slice方法。
//法四:利用concat
console.log(Array.prototype.concat.apply([], arg));
</script>
</body>
3.数组扁平化
数组扁平化是指将一个多维数组变为一个一维数组
const arr = [1, [2, [3, [4, 5]]], 6]
// => [1, 2, 3, 4, 5, 6]
//法一:使用内置的flat()
const res1 = arr.flat(Infinity)
//法二:用正则表达式
const res2 = JSON.stringify(arr).replace(/\[|\]/g,"").split(',')
//此时数组元素为字符串类型,若用arr.join()会将中括号自动去掉
//法三:用 reduce 实现数组的 flat 方法(重点关注)
function flatmy(ary) {
//注意函数要有返回值
return ary.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flatmy(cur) : cur)
}, [])
}
console.log(flatmy(arr))
// 法四:函数递归
const res4 = []
const fn = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
fn(arr[i])
} else {
res4.push(arr[i])
//或 res4 = res4.concat(arr[i])
}
}
return res4
}
console.log(fn(arr))
//法五:调用toString
console.log(arr.toString()); //1,2,3,4,5,6
console.log(arr.toString().split(',').map(item => item-0)) //若没有map函数隐式转换则数组里的元素为字符串类型
4.数组去重
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]
// => [1, '1', 17, true, false, 'true', 'a', {}, {}]
// 法一:用new Set方法
let res = Array.from(new Set(arr))
// 法二:用indexOf
let res2 = []
for(let v of arr){
if(res2.indexOf(v)==-1) res2.push(v)
}
/*法三:用filter */
function myUnique(arr){
return arr.filter((v,index)=>{
return arr.indexOf(v)===index
})
}
// 法四:用sort,排序后相同的元素在相邻位置
function unique(arr) {
arr = arr.sort()
var res= []
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
res.push(arr[i])
}
}
return res
}
console.log(unique(arr))
5.数组使用Math.max
Math.max支持传入多个参数,但不可传入一个数组(否则为NaN
),若想使用可用一下方法
Math.max.apply(null,arr)
Math.max(...arr)
手写数组内置方法
1. Array.prototype.filter
filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素
语法:var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
参数:
callback
:用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数
element
:数组中当前正在处理的元素。
index可选
:正在处理的元素在数组中的索引。
array可选
:调用了 filter 的数组本身。
thisArg可选
:执行 callback 时,用于 this 的值。
Array.prototype.myFilter = function(callback,thisArg){
if(typeof callback != 'function' ) {
throw new TypeError(callback +'不是函数')
}
if(!Array.isArray(this)){
throw new TypeError('必须为数组才可调用此方法')
}
let res = []
//确定回调函数的this指向,看是否传了第二个参数,若无则设为window调用
let context = arguments[1]||window
for(let i = 0; i < this.length; i++){
callback.call(context,this[i],i,this) && res.push(this[i])
}
return res
}
2. Array.prototype.map
map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成
语法:var new_array = arr.map(function callback(currentValue[, index[, array]]) [, thisArg])
,参数大致与filter相同
Array.prototype.myMap = function (callback, thisArg) {
if (typeof callback != 'function') {
throw new TypeError(callback + '不是函数');
}
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let res = []
let context = arguments[1] || window
for (let i = 0; i < this.length; i++) {
res.push(callback.call(context, this[i], i, this))
}
return res
};
3. Array.prototype.reduce(难点)
reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值
语法:Array.reduce(callback(previousValue, currentValue[, currentIndex[, array]])[, initialValue])
参数:
previousValue
:上一次调用 callbackFn 时的返回值。第一次调用时为初始值initialValue||array[0]
currentValue
:数组中正在处理的元素。在第一次调用时若指定了初始值 initialValue,其值则为 array[0],否则为 array[1]。
currentIndex
:数组中正在处理的元素的索引
initialValue
:可选,作为第一次调用 callback 函数时参数 previousValue 的值。若指定了 initialValue则 currentValue
将使用数组第一个元素
Array.prototype.myReduce = function (callback, initialValue) {
if (typeof callback != 'function') {
throw new TypeError(callback + '不是函数');
}
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let accumulator = initialValue
if(accumulator === undefined){
//若未设初始值则赋值为数组的第一个元素
accumulator = this[0]
//数组为空且初始值 initialValue 未提供时会报错
if(accumulator === undefined) throw new TypeError('无初始值时数组要为非空');
}
//若给定初始值则起始索引号为0
let startIndex = initialValue !== undefined ? 0 : 1;
for (let i = startIndex; i < this.length; i++) {
accumulator = callback.call(undefined,accumulator,this[i], i, this);
}
return accumulator;
};
4. Array.prototype.forEach
forEach() 方法对数组的每个元素执行一次给定的函数,注意返回值为undefined
语法:arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
Array.prototype.myForEach = function (callback, thisArg) {
if (typeof callback != 'function') {
throw new TypeError(callback + '不是函数');
}
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let context = arguments[1] || window;
for (let i = 0; i < this.length; i++) {
callback.call(context, this[i], i, this);
}
};
5. Array.prototype.some
some() 方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。
语法:arr.some(callback(element[, index[, array]])[, thisArg])
Array.prototype.mySome = function(callback,thisArg){
if (typeof callback != 'function') {
throw new TypeError(callback + '不是函数');
}
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let context = arguments[1] || window
for(let i =0 ; i < this.length; i++){
if( callback.call(context,this[i],i,this)){
return true
}
}
return false
}
6. Array.prototype.find
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
语法:Array.find(callback(element[, index[, array]])[, thisArg])
Array.prototype.myFind = function(callback,thisArg){
if (typeof callback != 'function') {
throw new TypeError(callback + '不是函数');
}
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let context = arguments[1] || window
for(let i =0 ; i < this.length; i++){
if( callback.call(context,this[i],i,this)){
return this[i]
}
}
return undefined
}
7. Array.prototype.unshift
unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)
语法:arr.unshift(element1, ..., elementN)
Array.prototype.myUnshift = function () {
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let len = arguments.length;
this.length += len;
//注意要从后往前循环,防止后面的值都被覆盖为前面arguments的值
for (let i = this.length - 1; i >= 0; i--) {
//当i小于传入的参数时取传入的参数,否则取原先的值
this[i] = i < len ? arguments[i] : this[i - len];
}
return this.length;
};
8. Array.prototype.join
join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符
语法:arr.join([separator])
参数:separator
为可选,指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,)分隔。如果separator是空字符串 (""),则所有元素之间都没有任何字符。
如果一个元素为 undefined 或 null,它会被转换为空字符串
Array.prototype.myJoin = function (s = ',') {
if (!Array.isArray(this)) {
throw new TypeError('必须为数组才可调用此方法');
}
let str = '';
for (let i = 0; i < this.length; i++) {
//判断数组元素是否为undefined或null
if(this[i] === undefined || this[i] === null ) this[i] = ''
if (i === 0) str = `${this[i]}`;
else str = `${str}${s}${this[i]}`;
}
return str;
};
另外还有every、findIndex、includes、push等方法,实现比较简单便不做赘述
参考资料
JavaScript数组方法总结及手写的更多相关文章
- JavaScript数组方法大集合
JavaScript数组方法集合 本文总结一下js数组处理用到的所有的方法.自己做个笔记. 数组方法 concat() 合并两个或多个数组 concat()能合并两个或者多个数组,不会更改当前数组,而 ...
- 一站式超全JavaScript数组方法大全
一站式JavaScript数组方法大全(建议收藏) 方法一览表 详细操作 本人总结了JavaScript中有关数组的几乎所有方法(包含ES6之后新增的),并逐一用代码进行演示使用,希望可以帮助大家! ...
- JavaScript数组方法--every、some、fill
接上一篇,JavaScript数组方法--concat.push,继续其他的数组方法. every:every() 方法测试数组的所有元素是否都通过了指定函数的测试. 先看其使用方法: functio ...
- 【译】你应该了解的JavaScript数组方法
让我们来做一个大胆的声明:for循环通常是无用的,而且还导致代码难以理解.当涉及迭代数组.查找元素.或对其排序或者你想到的任何东西,都可能有一个你可以使用的数组方法. 然而,尽管这些方法很有用,但是其 ...
- JavaScript数组方法大全(推荐)
原网址:http://www.jb51.net/article/87930.htm 数组在笔试中经常会出现的面试题,javascript中的数组与其他语言中的数组有些不同,为了方便之后数组的方法学习, ...
- JavaScript 数组方法处理字符串 prototype
js中数组有许多方法,如join.map,reverse.字符串没有这些方法,可以“借用”数组的方法来处理字符串. <!doctype html> <html lang=" ...
- 2018.2.27 JavaScript数组方法应用
JavaScript数组方法应用 1.找出元素item在给定数组arr中的位置 function indexOf(arr,item){ return arr.indexOf(item); } func ...
- JavaScript数组方法详解
JavaScript数组方法详解 JavaScript中数组的方法种类众多,在ES3-ES7不同版本时期都有新方法:并且数组的方法还有原型方法和从object继承的方法,这里我们只介绍数组在每个版本中 ...
- JavaScript数组方法速查,32个数组的常用方法和属性
JavaScript数组方法速查手册极简版 http://30ke.cn/doc/js-array-method JavaScript数组方法速查手册极简版中共收了32个数组的常用方法和属性,并根据方 ...
随机推荐
- apparmor 源码分析
这里不对apparmor做介绍,记录一下源码分析过程. 初始化 static int __init apparmor_init(void) -> security_add_hooks(appar ...
- 2020年DevOps工程师入门指南
DevOps兴起于2010年代,到现在DevOps已经在行业中拥有了一席之地,并在继续发展壮大. 有兴趣成为一名DevOps工程师吗?如果想要成为一名DevOps工程师,需要做到以下五点: 要有开发者 ...
- latex中显示代码
如何在latex中添加代码模块 首先在开头导入以下的包 \usepackage{listings} \usepackage{ctex} % 用来设置附录中代码的样式 \lstset{ basicsty ...
- ElasticSearch7.3学习(二十四)----相关度评分机制详解
1.算法介绍 relevance score(相关性分数) 算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term freque ...
- 操作系统:Tails
Tor是一个网络 如今,Tor浏览器可能是Tor的代言人,但Tor的真正力量在于Tor网络.大家都知道,"Tor"实际上是"The Onion Router"( ...
- Spring-Batch将CSV文件转为XML文件
1 介绍 用Spring Batch实现一个简单的需求,将csv文件转换成xml文件. csv文件如下:record.csv username, user_id, transaction_date, ...
- 好客租房57-props深入(4props的默认值)
1给props设置默认值 //导入react import React from 'react' import ReactDOM from 'react-dom' import ...
- Spring是如何整合JUnit的?JUnit源码关联延伸阅读
上一篇我们回答了之前在梳理流程时遇到的一些问题,并思考了为什么要这么设计. 本篇是<如何高效阅读源码>专题的第十二篇,通过项目之间的联系来进行扩展阅读,通过项目与项目之间的联系更好的理解项 ...
- 关于『进击的Markdown』:第二弹
关于『进击的Markdown』:第二弹 建议缩放90%食用 众里寻他千百度,蓦然回首,Markdown却在灯火灿烂处 MarkdownYYDS! 各位早上好! 我果然鸽稿了 Markdown 语法 ...
- Python装饰器,Python闭包
可参考:https://www.cnblogs.com/lianyingteng/p/7743876.html suqare(5)等价于power(2)(5):cube(5)等价于power(3)(5 ...