数组也是js中常用的数据类型,下面通过一些场景来描述它的使用。
判断变量类型,数组or对象
instanceof
instanceof用于判断构造函数的prototype属性是否出现在对象的原型链中的任何位置。
array也是引用类型,通过instanceof来判断变量是数组还是对象。但因为数组是属于对象的,所有判断全应该先是否为数组,再判断是否为对象。
可以封装一个函数
1 2 3 4 5 6 7 8 9
| function myDataType(o){ if(o instanceof Array){ return 'Array' }else if(o instanceof Object){ return 'Object' } else{ return 'not is a object type' } }
|
construtor
也可以通过构造函数判断,因为每一个对象的实例都是通过构造函数生成的,所以可以直接判断constructor属性。
1 2
| let a=[1,2,3] console.log(a.constructor===Array)
|
construtor与__
proto__
属性:proto表示的是隐式原型,指向构造函数的原型
1
| [].__proto__===[].constructor.prototype//true
|
可以对其进行封装
1 2 3 4 5 6 7 8 9 10 11
| function myDataType(o){ let constructor=o.__proto__.constructor||o.constructor if(constructor===Array){ return 'Array' }else if(constructor===Object){ return 'Object' } else{ return 'not is a object type' } } }
|
但是早期ie不支持__
proto__
属性,因此并不完美。
toString()
任何数据类型都会包含toString()函数,通过借助call函数,通过toString的返回值进行判断。
1 2
| let a=[1,2,3] console.log(Object.prototype.toString.call(a))//[object Array]
|
Array.isArray()
使用这个方法可以直接判断是否为数组,但是不能判断是否为对象
1 2
| let a=[1,2,3] Array.isArray(a)
|
filter()函数过滤满足条件的值
filter返回一个满足条件的新数组,不改变原来的数组,可以通过自定义方法来过滤复杂数据类型的数组。filter接收一个函数作为参数,返回值为true的元素将被加入新数组。
还可以利用filter进行去重
reduce()
reduce作为累加器,理解它需要知道参数的意义,MDN中的定义如下
1 2
| arr.reduce(callback(accumulator, currentValue)) //内的参数为可选
|
其中accumulator
:上一次调用回调时返回的累积值,或initialValue
currentValue
:数组中正在处理的元素
index
:数组中正在处理的当前元素的索引
array
:数组本身
统计元素出现次数
1 2 3 4 5 6 7
| let countOccurrences=function(arr){ return arr.reduce(function(accumulator,currentValue){ accumulator[currentValue]?accumulator[currentValue]++:accumulator[currentValue]=1 return accumulator },{}) } console.log(countOccurrences([1,2,3,4,5,6,7]))
|
我自己在chrome上运行时,想偷个懒将函数名称写成count,然后报错
1
| Identifier 'count' has already been declared
|
这样的函数名称不能在js中定义,可能因为是关键词或者保留字吧,换一个名称就行了。
多维度统计数据
场景:汇率不同,将一组人民币分别换算成美元和欧元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| let items = [{ price: 10 }, { price: 20 }, { price: 300 }] let reduces = { //分别计算不同汇率 totalEuros: function (state, item) { return state.euros += item.price * 0.1265 }, totalDolls: function (state, item) { return state.dolls += item.price * 0.1487 } } let managerReduces = function (reduces) { return function (state, item) { return Object.keys(reduces).reduce( function (next, key) { //此处next累加器只是占个位,因为真正的值都是reduces里面的函数返回的 reduces[key](state, item) return state }, {} ) } } //将callback函数封装成manager,设置初始值 let totals = items.reduce(managerReduces(reduces), { euros: 0, dolls: 0 }) console.log(totals)
|
找出数组中的最值
利用Math.min()和Math.max(),由于 min
是 Math
的静态方法,所以应该像这样使用:Math.min()
,而不是作为你创建的 Math
实例的方法(Math 不是构造函数)。
1 2 3 4 5
| let nums=[1,3,0] Array.prototype.min = function () { return Math.min.apply({},this) } console.log(nums.min())
|
为Array类型添加静态函数min,apply传入的{},表示当前执行环境的全局对象,this代表传入的数组。不能直接调用,除非直接传入数据👇,但是实际开发中传入的往往是数组
1
| let minNum=Math.min(1,3,0)
|
1 2 3 4 5 6
| Array.prototype.min = function () { return this.reduce(function(pre,cur){ return pre>cur?cur:pre }) }
|
原生的sort排序后直接取值
1 2 3 4
| //最小值 nums.sort((a, b) => a - b)[0]) //最大值 nums.sort((a, b) => a - b)[nums.length-1])
|
还有for循环就不说了
数组遍历
有for、forEach()、map()、filter()、reduce()、find()、some()+every()函数的方法
其中,find是es6新添加的,其他都是es5新增的,所以我们可以做兼容性处理(手动实现API)