常见js手写题1
函数防抖、函数节流、函数柯里化、二分查找、InstanceOf、call、apply,bind
函数防抖
function debounce(fn,wait){ //防抖:每次点击重置定时器 let timer = null return (...arg)=>{ let self = this clearTimeout(timer) timer = setTimeout(()=>{ fn.apply(self,arg) },wait) } }
函数节流
function throttle(fn,wait){ //节流:规定时延内重复作用无效
let flag = false
return (...arg)=>{
let self = this
if(flag){retun}
flag = true;
setTimeout(()=>{
fn.apply(self,arg)
},wait)
}
}
函数柯里化
function curry(fn,arg=[]){ //传入一个函数,返回一个函数
let length = fn.length
return (...rest)=>{
let _arg = arg.slice(0) //获得现有参数数组深拷贝副本
_arg.push(...rest) //将函数参数传入现存参数数组
if(length > _arg.length){
return curry.call(this,fn,_arg) //参数未传够则递归
} else {
fn.apply(this,_arg) }
}
}
二分查找
function binarySearch(arr,target){ //输入数字,目标;返回找到的下标
let left =0,
right =arr.length-1,
mid;
while(left < right){
mid =Math.floor((left+right)/2);
if(target > arr[mid]){
left = mid+1
}
else if (targrt < arr[mid]){
right = mid-1
}
else {
return mid
}
}
}
InstanceOf实现
InstanceOf = (A,B)=>{ //A:需判定的子类;B:父类
let a = A.__proto__;
let b = B.prototype;
while(true){
if(a === b){ return true } //原型继承条件:子类隐式原型指向父类显示原型
if(a === null){return false}
a = a.__proto__
}
}
call实现
call、apply修改函数作用域立即执行;不同的是apply接收一个参数数组
Function.prototype.myCall = function(context,...args){
context = context || window //修改当前上下文的指向
//let fn = Symbol('fn') //保证fn为一个全局唯一的值
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与call的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myCall(obj,'Alice','Bob')
apply实现
Function.prototype.myApply = function(context,args){
context = context || window //修改当前上下文的指向
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与apply的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myApply(obj,['Alice','Bob'])
bind实现
bind返回一个闭包函数,通过再次调用来执行
Function.prototype.myBind = function(context,...args){
context = context || window //修改当前上下文的指向
context.fn = this
return (...rest)=>{
context.fn(...args,...rest)
}
}
//定义用与bind的函数和this需要指向的对象
let bindObj={
value : 5
}
let bindFn = function(a,b,c){
console.log(this.value, a, b, c)
}
//执行bind函数,返回一个闭包,再次调用执行
let res = bindFn.myBind(bindObj,1,2) //绑定函数的调用对象为bindObj
res(3) //执行并还可传参数
function curry(fn,arg=[]){ //传入一个函数,返回一个函数 let length = fn.length return (...rest)=>{ let _arg = arg.slice(0) //获得现有参数数组深拷贝副本 _arg.push(...rest) //将函数参数传入现存参数数组 if(length > _arg.length){ return curry.call(this,fn,_arg) //参数未传够则递归 } else { fn.apply(this,_arg) } } }
二分查找
function binarySearch(arr,target){ //输入数字,目标;返回找到的下标
let left =0,
right =arr.length-1,
mid;
while(left < right){
mid =Math.floor((left+right)/2);
if(target > arr[mid]){
left = mid+1
}
else if (targrt < arr[mid]){
right = mid-1
}
else {
return mid
}
}
}
InstanceOf实现
InstanceOf = (A,B)=>{ //A:需判定的子类;B:父类
let a = A.__proto__;
let b = B.prototype;
while(true){
if(a === b){ return true } //原型继承条件:子类隐式原型指向父类显示原型
if(a === null){return false}
a = a.__proto__
}
}
call实现
call、apply修改函数作用域立即执行;不同的是apply接收一个参数数组
Function.prototype.myCall = function(context,...args){
context = context || window //修改当前上下文的指向
//let fn = Symbol('fn') //保证fn为一个全局唯一的值
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与call的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myCall(obj,'Alice','Bob')
apply实现
Function.prototype.myApply = function(context,args){
context = context || window //修改当前上下文的指向
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与apply的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myApply(obj,['Alice','Bob'])
bind实现
bind返回一个闭包函数,通过再次调用来执行
Function.prototype.myBind = function(context,...args){
context = context || window //修改当前上下文的指向
context.fn = this
return (...rest)=>{
context.fn(...args,...rest)
}
}
//定义用与bind的函数和this需要指向的对象
let bindObj={
value : 5
}
let bindFn = function(a,b,c){
console.log(this.value, a, b, c)
}
//执行bind函数,返回一个闭包,再次调用执行
let res = bindFn.myBind(bindObj,1,2) //绑定函数的调用对象为bindObj
res(3) //执行并还可传参数
InstanceOf = (A,B)=>{ //A:需判定的子类;B:父类 let a = A.__proto__; let b = B.prototype; while(true){ if(a === b){ return true } //原型继承条件:子类隐式原型指向父类显示原型 if(a === null){return false} a = a.__proto__ } }
call实现
call、apply修改函数作用域立即执行;不同的是apply接收一个参数数组
Function.prototype.myCall = function(context,...args){
context = context || window //修改当前上下文的指向
//let fn = Symbol('fn') //保证fn为一个全局唯一的值
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与call的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myCall(obj,'Alice','Bob')
apply实现
Function.prototype.myApply = function(context,args){
context = context || window //修改当前上下文的指向
context.fn = this
let res = eval('context.fn(...args)')
delete context.fn //fn是context的属性,调用后删除
return res
}
//定义用与apply的函数和this需要指向的对象
function test (a,b){
console.log(a,b,'say',this.words?this.words:'---')
}
let obj = { words:'hello' }
//执行
test.myApply(obj,['Alice','Bob'])
bind实现
bind返回一个闭包函数,通过再次调用来执行
Function.prototype.myBind = function(context,...args){
context = context || window //修改当前上下文的指向
context.fn = this
return (...rest)=>{
context.fn(...args,...rest)
}
}
//定义用与bind的函数和this需要指向的对象
let bindObj={
value : 5
}
let bindFn = function(a,b,c){
console.log(this.value, a, b, c)
}
//执行bind函数,返回一个闭包,再次调用执行
let res = bindFn.myBind(bindObj,1,2) //绑定函数的调用对象为bindObj
res(3) //执行并还可传参数
Function.prototype.myCall = function(context,...args){ context = context || window //修改当前上下文的指向 //let fn = Symbol('fn') //保证fn为一个全局唯一的值 context.fn = this let res = eval('context.fn(...args)') delete context.fn //fn是context的属性,调用后删除 return res } //定义用与call的函数和this需要指向的对象 function test (a,b){ console.log(a,b,'say',this.words?this.words:'---') } let obj = { words:'hello' } //执行 test.myCall(obj,'Alice','Bob')