用js實現filter、map、forEach、every、some、find、indexOf、join、fill、toString、flat、push、reduce等等方法...

V8引擎肯定沒有這麼垃圾,俺就是用解釋性語言做的語法來解釋語法,接下來介紹一下這千篇一律的垃圾代碼

先寫兩個判斷,大部分會用到

function check(fn){		// 檢查形參是否爲函數
	if(typeof fn !=='function'){
		throw new TypeError (fn + ' is not a function')
	}
}

1. filter

篩選出符合條件的值,push進新數組並返回它



Array.prototype._filter = function(callback){
	if(callback) check(callback)
	
	for(let i=0;i<this.length;i++){
		let result = callback(this[i],i,this)
		if(result) tempArr[tempArr.length] = this[i]
	}
	return tempArr
}


const arr = [1,-1,2,3]
let boo = arr._filter( item => item<0 )
console.log(boo) // [-1]

2. map

對原數組循環處理,並可return一個新數組。(es6的map很強大的,這個是閹割版的map,太監map)

這個最複雜了,嗎的。。。
map的this指向我搞好長時間了,還是不會,求大神指教

Array.prototype._map = function(callback){
	if(callback) check(callback)
	
	let tempArr = []
	for(let i=0;i<this.length;i++){
		tempArr[tempArr.length] = callback(this[i],i,this)
	}
	return tempArr
}


const arr = [1,-1,2,3]
let returnMap = arr._map((item,index)=>{
	return {
		item: item,
		a: index,
	}
})
console.log(JSON.stringify(returnMap)) 
// [{"item":1,"a":0},{"item":-1,"a":1},{"item":2,"a":2},{"item":3,"a":3}]

3. forEach

循環輸出數組的每一項

Array.prototype._forEach = function(callback){
	if(callback) check(callback)
	
	for(let i=0;i<this.length;i++){
		callback(this[i],i,this)
	}
}


const arr = [1,-1,2,3]
arr._forEach(item=>{
	console.log(item)
})	// 1,-1,2,3

4. every

返回一個布爾值。如果數組裏的每一項都符合判斷返回true,有一項不符合則返回false。

Array.prototype._every = function(callback){
	if(callback) check(callback)
	
	for(let i=0;i<this.length;i++){
		let result = callback(this[i],i,this)
		if(!result) return false
	}
	return true
}


const arr = [1,-1,2,3]
let boo = arr._every(item=>item>0)
console.log(boo) // false

5. some

返回一個布爾值。如果數組裏有一項符合判斷就返回true,每一項都不符合則返回false。

Array.prototype._some = function(callback){
	if(callback) check(callback)
	
	for(let i=0;i<this.length;i++){
		let result = callback(this[i],i,this)
		if(result) return true
	}
	return false
}


const arr = [1,-1,2,3]
let boo = arr._some(item=>item>0)
console.log(boo) // true

6. find

找到數組中第一個符合條件的值,並返回它

Array.prototype._find = function(callback){
	if(callback) check(callback)
	
	let temp = undefined
	for(let i=0;i<this.length;i++){
		let result = callback(this[i],i,this)
		if(result){
			temp = this[i]
			return temp;
		}
	}
	return temp;
}


const arr = [1,-1,2,3]
let boo = arr._find(item=>item>0)
console.log(boo) // 1

7. findIndex

找到第一個符合條件的值的下標,並返回它。

Array.prototype._findIndex = function(callback){
	if(callback) check(callback)
	
	let temp = undefined
	for(let i=0;i<this.length;i++){
		let result = callback(this[i],i,this)
		if(result){
			temp = i
			return temp;
		}
	}
	return temp;
}


const arr = [{a: 1},{a: 2},{a: 3}]
let boo = arr._findIndex(item=>item.a>0)
console.log(boo) // 1

8. indexOf(數組)

查找數組中的元素,存在返回下標,不存在返回-1。

Array.prototype._indexOf = function(str,start=0){
	let len = this.length
	if(start>=len || typeof start !== 'number') return -1;
	if(start>=0){
		for(let i=start;i<this.length;i++){
			if(this[i] === str){
				return i;
			}
		}
	}else{
		let reseverLen = len - 0 - start
		for(let i=reseverLen;i>0;i--){
			if(this[i] === str){
				return i;
			}
		}
	}
	return -1;
}

 
const arr = [3,{a: 1},{a: 2},{a: 3},5,{a:4},{a: 5},0,10,11]
let boo = arr._indexOf(5,-1)
console.log(boo)	// 4

9. includes(數組)

查找數組中的元素,存在返回true,不存在返回false。

Array.prototype._indexOf = function(str,start=0){
	for(let i=start;i<this.length;i++){
		if(this[i] === str){
			return i;
		}
	}
	return -1;
}


const arr = [{a: 1},{a: 2},{a: 3},5]
let boo = arr._indexOf(6)
console.log(boo) // -1

10. join

數組轉字符串,可傳拼接參數

Array.prototype._join = function(str=','){
	let tempStr = ''
	for(let i=0;i<this.length;i++){
		if(i === this.length-1){
			tempStr += this[i]
		}else{
			tempStr += this[i] + '' + str
		}
	}
	return tempStr
}

 
const arr = [3,4,5]
let boo = arr._join('-')
console.log(boo)	// 3-4-5

11. fill

填充數組

/*
 * @param param {any} 必填,爲替換的項
 * @param start {number} 起始填充位置,按length計算,非索引
 * @param end {number} 結束填充位置,按length計算,非索引
 * @return this Array<any> 返回改變後的原數組
 */
Array.prototype._fill = function(param,start,end){
	let max = end || this.length
	for(let i=start || 0;i<max;i++){
		this[i] = param
	}
	return this;
}

 
const arr = [1,2,3,4,5]
arr._fill('123',2,4)
console.log(arr)	// [ 1, 2, "123", "123", 5 ]

12. toString(數組、對象、數字)

將數組轉成字符串

Array.prototype._toString = function(){
	const param = this
	return param + ''
}

 
const arr = [1,24,[5],9,{}]
console.log(arr._toString()) // 1,24,5,9,[object Object]

13. isArray

判斷一個值是否爲數組,是返回true,否返回false

Array._isArray = function(param){
	return Object.prototype.toString.call(param) === '[object Array]'
}

 
const arr = [1,2,3]
console.log(Array._isArray(arr))	// true

14. reverse

js的反轉數組方法,在此基礎上加了個沒什麼用處的功能,可以選擇指定位置反轉,因爲加了擴展運算符,好像也不算純粹的js了

/*
 * @param start {number|string} 起始倒序位置,按索引計算
 * @param end {number|string} 結束倒序位置,按索引值計算
 * @return this Array<any> 返回改變後的原數組
 */
Array.prototype._reverse = function(start,end){	
	const len = this.length-1
	if(start > len || end > len){
		throw new TypeError ('start or end is too long')
	}
	const tempArr = [].slice.call(this)
	let index = 0
	if(!start && !end){
		for(let i=len;i>=0;i--){
			this[index] = tempArr[i]
			index++
		}
	}else if(start && !end){
		index = start
		for(let i=len;i>=start;i--){
			this[index] = tempArr[i]
			index++
		}
	}else{
		index = end
		for(let i=start;i<=end;i++){
			this[index] = tempArr[i]
			index--
		}
	}
	return this
}

 
const arr = [1,2,3,4,5,6]
arr._reverse()		// [ 6, 5, 4, 3, 2, 1 ]
console.log(arr)
arr._reverse(2)
console.log(arr)	// [ 6, 5, 2, 3, 4, 1]

15. sort

對數組進行排序,這個就不是純粹的js了,因爲用到了String的方法

Array.prototype._sort = function(callback){
	if(!callback){	// 如果沒有傳入回調函數,則按照ASCII碼進行排序
		let tempArr = []
		let str = ''
		for(let i=0;i<this.length;i++){
			for(let j=0;j<this.length;j++){
				if((this[j]+'').charCodeAt(0) > (this[i]+'').charCodeAt(0)){
					str = this[j]
					this[j] = this[i]
					this[i] = str
				}
			}
		}
	}else{
		check(callback)
		let str = ''
		for(let i=0;i<this.length;i++){  
			for(let j=i;j<this.length;j++){
				if(callback(this[i],this[j])>0){
					str = this[j]
					this[j] = this[i]
					this[i] = str
				}
			}
		}
	}
	return this;
}

const arr = [{age: 3},{age: 66},{age: 5}]
console.log(arr._sort((a,b)=>{
	return a.age - b.age
}))

16. flat

展開多維數組,默認參數是1,也就是說默認展開二維數組。
可選參數: Infinity(無窮大)不需填入具體數字,不管多少維的數組都可以將其扁平化

Array.prototype._flat = function(param){
	if(param !== Infinity) param+=1
	let tempArr = [],index = 0,that = this
	function fn(that){
		if(param === Infinity){
			for(let i=0;i<that.length;i++){
				if(Object.prototype.toString.call(that[i]) === '[object Array]'){
					fn(that[i])
				}else{
					if(that[i] !== undefined){
						tempArr[tempArr.length] = that[i]
					}
				}
			}
		}else{
			for(let i=0;i<that.length;i++){
				if(Object.prototype.toString.call(that[i]) === '[object Array]'){
					if(index+1>=param){
						tempArr[tempArr.length] = that[i]
						return tempArr;
					}
					index++
					fn(that[i])
				}else{
					if(that[i] !== undefined){
						tempArr[tempArr.length] = that[i]
					}
				}
			}
		}
	}
	fn(that)
	return tempArr;
}

const arr = [7,[1,0,[3,[4,[5,6,7,8]]]]]
console.log(arr._flat(3))  // [ 7, 1, 0, 3, 4, (4) […] ]

17. flatMap

相當於執行了一遍深度爲1的flat,和一遍map

Array.prototype._flatMap = function(callback){
	if(callback) check(callback)
---------------------------------用push	
	let tempArr = new Array()
	for(let i=0;i<this.length;i++){
		if(Array.isArray(this[i])){
			tempArr.push(...this[i])
		}else{
			tempArr.push(callback(this[i],i,this))
		} 
	}
	return tempArr
---------------------------------用push	

---------------------------------不用push	
	let tempArr = new Array()
	for(let i=0;i<this.length;i++){
		if(Array.isArray(this[i])){
			 fn(this[i])
		}else{
			tempArr[tempArr.length] = callback(this[i],i,this)
		} 
	}
	function fn(arr){
		for(let i=0;i<arr.length;i++){
			tempArr[tempArr.length] = arr[i]
		}
	}
	return tempArr
---------------------------------不用push	
}

const arr = [1,3,['123',[4]],6]
console.log(arr._flatMap((item)=>{
	return item*2
}))

18. push

真正的push肯定沒有這麼渣

Array.prototype._push = function(){
	for(let i in arguments){
		this[this.length] = arguments[i]
	}
	return this.length
}

const arr = [1,3,['123',[4]],6]
arr._push({a: 1},{b: 2})		
console.log("arr:::", arr)	// [ 1, 3, (2) […], 6, {…}, {…} ]

19. pop

同上

Array.prototype._pop = function(){
	if(!this.length || this.length<=0) return undefined;
	let param = this[this.length - 1]
	this.length = this.length - 1
	return param
}

const arr = [1,3,['123',[4]],6]
let param = arr._pop()	
console.log(param)	// 6
console.log("arr:::", arr)	// [ 1, 3, (2) […] ]

20. concat

這個要寫我也是用擴展運算符,或者arguments,跟上面套路一樣,沒啥意思就不寫了

21. reduce

對數組提供一個累加器,在reduce內部可對這個累加器進行操作。
當沒有初始值時,pre爲數組下標0項,item爲數組下標1項
有初始值時,pre爲初始值,item爲數組下標0項

Array.prototype._reduce = function(callback,pre){
	if(callback) check(callback)
	if(this.length<=0){
		throw new TypeError('reduce of empty array with no initial value')
	}
	let start = pre?0:1
	let tempResult = pre || this[0]
	for(let i=start;i<this.length;i++){
		tempResult = callback(tempResult,this[i],i,this)
	}
	return tempResult
}


const arr = [1,2,3]
let result = arr._reduce((pre,item,index,arr)=>{
	return pre + item
})
console.log(result)	// 6
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章