es6的方法一直在用,尤其是数组方法,简化了很多对数组的操作。但是对于其实现原理,一直也没有深究,最近在项目中,遇到了一个需求:需要对之前的数组元素进行过滤,过滤后的元素需要重新整合属性值,且不改变原有数组的元素。在用filter方法的时候,发现会改变其原有数组中的元素,遂萌生了自己重写该方法的想法,即产生了该篇文章。这篇文章会分析es6语法中数组的常用方法,并自己手动实现这些方法。 1. forEach方法:
Array.prototype.MyForEach = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
for(let i = 0; i<_len; i++){
cb.apply(_this,[_arr[i],i, _arr])
}
}
2. map方法:
Array.prototype.MyMap = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
var _newArr = []
var res
for(let i = 0; i < _len; i++){
// ! 这样可以保证不改变原来的数组,对原来的map方法进行了改进
let newVal = deepClone(_arr[i])
res = cb.apply(_this,[newVal,i,_arr])
if(res){
_newArr.push(res)
}
}
return _newArr
}
3. filter方法:
Array.prototype.MyFilter = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
var _newArr = []
for(let i = 0; i<_len; i++){
// ! 这样可以保证不改变原来的数组,对原来的filter方法进行了改进
var newVal = deepClone(_arr[i])
if(cb.apply(_this,[newVal,i,_arr])){
_newArr.push(newVal)
}
}
return _newArr
}
4. every方法:
Array.prototype.MyEvery = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
let res = true
for(let i = 0; i<_len; i++){
if(!cb.apply(_this,[_arr[i],i,_arr])){
res = false
break
}
}
return res
}
5. some方法:
Array.prototype.MySome = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
let res = false
for(let i = 0; i<_len; i++){
if(cb.apply(_this,[_arr[i],i,_arr])){
res = true
break
}
}
return res
}
6. find方法:
Array.prototype.MyFind = function(cb){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
var res
for(let i = 0; i < _len; i++){
if(cb.apply(_this,[_arr[i],i,_arr])){
res = _arr[i]
break
}
}
return res
}
7. findIndex方法:
Array.prototype.MyFindIndex = function(){
var _arr = this
var _len = _arr.length
var _this = arguments[1] || window
var res
for(let i = 0; i < _len; i++){
if(cb.apply(_this,[_arr[i],i,_arr])){
res = i
break
}
}
return res
}
8. reduce方法:
Array.prototype.MyrReduce = function(cb){
var _arr = this
var _len = _arr.length
var initial = arguments[1]
for(let i = 0; i < _len; i++){
if(i === 0 && initial === undefined){
initial = _arr[0]
}else{
initial = cb.apply(window,[ initial, _arr[i], i, _arr ])
}
}
return initial
}
9. reduceRight方法:
Array.prototype.MyReduceRight = function(cb){
var _arr = this
var _len = _arr.length
var initial = arguments[1]
for(let i = _len - 1; i >= 0; i--){
if(i === _len - 1 && initial === undefined){
initial = _arr[_len - 1]
}else{
initial = cb.apply(window,[ initial, _arr[i], i, _arr ])
}
}
return initial
}
10. 辅助方法deepClone:
// 对象的深拷贝
function deepClone(cloneObj,target){
var _target = target|| {}
for(let key in cloneObj){
// hasOwnProperty判断是否是对象自身属性,不包括继承的属性
if(cloneObj.hasOwnProperty(key)){
if(typeof cloneObj[key] === 'object' && cloneObj[key] !== null){
_target[key] = Object.prototype.toString.call(cloneObj) === '[object Array]' ? [] : {}
deepClone(cloneObj[key],_target[key])
}else{
_target[key] = cloneObj[key]
}
}
}
return _target
}