前言
常言说的好,基础不牢,地动山摇,这些常见的js基础函数你会了嘛?
01.手写数组filter函数
- 案例
let arr = [1,2,3,4,5,6]
//筛选出大于3的数字
let newArr = arr.filter(item => {
return item > 3
})
console.log(newArr); //[4,5,6]
手写filter
Array.prototype.newFilter = function(callback,thisArg){
if(this == undefined){
throw new TypeError('this is null or not defined')
}
if(typeof callback != 'function'){
throw new TypeError(callback + 'is not a function')
}
const res = []
const O = Object(this)
const len = O.length >>> 0 // >>>0 保证len为num,且为正整数
for(let i = 0 ;i< len ;i++){
if(i in O){
if(callback.call(thisArg,O[i],i,O)){
res.push(O[i])
}
}
}
return res
}
let newArr1 = arr.newFilter(item => {
return item > 3
})
console.log(newArr1); //[4,5,6]
02.手写数组map函数
- 案例
let arr = [1,2,3,4,5]
let newArr = arr.map(item => {
return item * 2
})
- 手写map函数
Array.prototype.newMap = function(callback,thisArg){
console.log(callback,thisArg);
if(this == undefined){
throw new TypeError('this is null or not defined')
}
if(typeof callback != 'function'){
throw new TypeError(callback + 'is not a function')
}
const res = []
const O = Object(this)
const len = O.length >>> 0
for(let i = 0 ;i < len ;i++){
if(i in O){
res[i] = callback.call(thisArg,O[i],i,this)
}
}
return res
}
let newArr1 = arr.newMap(item => {
return item * 2
})
console.log(newArr1);
03.手写数组forEach函数
forEach跟map类似,唯一不同的是forEach是没有返回值的
- 案例
let arr = [1,2,3,4,5]
let newArr = []
arr.forEach(item => {
newArr.push(item * 2)
})
console.log(newArr); // [ 2,4,6,8,10 ]
手写forEach
Array.prototype.newForEach = function(callback,thisArg){
if(this == undefined){
throw new TypeError('this is null or not defined')
}
if(typeof callback != 'function'){
throw new TypeError(callback + 'is not a function')
}
const O = Object(this)
const len = O.length >>> 0
while(k < len){
if(k in O){
callback.call(thisArg,O[k],k,O)
}
k++
}
}
04.手写数组reduce函数
- 案例
const arr = [1, 2, 3, 4, 5, 6]
let sum = arr.reduce((prev, cur) => {
return prev + cur
}, 0)
console.log(sum); // 21
- 手写reduce函数
Array.prototype.newReduce = function (callback, initiaValue) {
if (this == undefined) {
throw new TypeError('this is null or not defined')
}
if (typeof callback != 'function') {
throw new TypeError(callback + 'is not a function')
}
const O = Object(this)
const len = this.length >>> 0
let accumulator = initiaValue
let k = 0
if (accumulator === undefined) {
while (k < len && !(k in O)) {
k++
}
// 如果超出数组界限还没有找到累加器的初始值,则TypeError
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
accumulator = O[k++];
}
while(k < len){
if(k in O){
accumulator = callback.call(undefined,accumulator,O[k],k,O)
}
k++
}
return accumulator
}
let sum1 = arr.newReduce((prev, cur) => {
return prev + cur
}, 0)
console.log(sum1); //21
05.手写apply函数
- 第一个参数是绑定的this,默认为
window,第二个参数是数组或类数组
// 第一个参数是绑定的this,默认为window,第二个参数是数组或类数组
Function.prototype.myApply = function(context=window,args){
if(typeof this != 'function'){
throw new TypeError('Type Error')
}
const fn = Symbol('fn')
context[fn] = this
const res = context[fn](...args)
delete context[fn]
return res
}
06.手写call函数
- 于apply唯一不同的是,call()方法接受的是一个
参数列表
Function.prototype.myCall(context = window,...args){
if(typeof this != 'function'){
throw new TypeError('Type Error')
}
const fn = Symbol('fn')
context[fn] = this
const res = context[fn](...args)
delete context[fn]
return res
}
07.手写bind函数
Function.prototype.myBind = function(context,...args){
if(typeof this != 'function'){
throw new Error('Type Error')
}
var self = this
return function F(){
if(this instanceof F){
return new self(...args,...arguments)
}
return self.apply(context,[...args,...arguments])
}
}
08.手写防抖函数
- 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
function debouced(fn,delay){
let timeout = null
return function(){
clearTimeout(timeout)
timeout = setTimeout(() => {
fn.call(this,...arguments)
},delay)
}
}
09.手写节流函数
- 高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。
const throttle = (fn,time){
let flag = true
return function(){
if(!flag) return
flag = false
setTimeout(() => {
fn.apply(this,arguments)
flag = true
},time)
}
}
10.函数珂里化
- 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式,这样便于再次调用,例如f(1)(2)
- 经典面试题:实现add(1)(2)(3)(4)=10; 、 add(1)(1,2,3)(2)=9;
function add() {
const _args = [...arguments];
function fn() {
_args.push(...arguments);
return fn;
}
fn.toString = function() {
return _args.reduce((sum, cur) => sum + cur);
}
return fn;
}