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