常见手写题目

实现防抖

1.搜索,就应该用防抖,当我连续不断输入时,不会发送请求;当一段时间内不输入了,才会发送一次请求;如果小于这段时间继续输入的话,时间会重新计算,也不会发送请求。
2.钮提交场景:防止多次提交按钮,只执行最后提交的一次

 function debounce (fn, wait=150){
   let timer = 0
    return function (...arguments) {
      if(timer){
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        fn.apply(this,arguments)
      }, wait);
    }
  }

实现节流

在第一次触发时不会执行,而是在 delay 秒之后才执行,当最后一次停止触发后,还会再执行一次函数,比例滚动

function throttle(fn, t) {
  let isRun = false
  return function (...arguments) {
    if(isRun){
      return
    }
    isRun = true
    setTimeout(() => {
      fn.apply(this,arguments)
      isRun = false
    }, t);
  }
 }

实现instanceOf

function _instanceOf(a,b){
   if(typeof a !== 'object' || a == null) {
     return false
   }
   // 因为 Object.getPrototypeOf(a) = a.__proto__
   let apro = Object.getPrototypeOf(a)
   // let apro = a.__proto__  //等同于上面一句
   while (apro) {
     if(apro == b.prototype){
       return true
     }
     apro = Object.getPrototypeOf(apro)
     // apro = apro.__proto__ //等同于上面一句
   }
   return false
 }

new的实现

  • 1.创建一个全新的对象obj,
  • 2.继承构造函数的原型:这个对象的__proto__要指向构造函数的原型prototype
    3.执行构造函数,使用 call/apply 改变 this 的指向(将obj作为this)
    4.返回值为object类型则作为new方法的返回值,否则返回新创建的对象obj
function myNew(fn,...args) {
    let obj = {}
    obj.__proto__ = fn.prototype
    let result = fn.apply(obj, args)
    // 等同于下面一句
    // result instanceof Object ? result: obj
    return typeof result === 'object' ? result: obj
  }

// 使用

 function Names(name,age) {
  this.name = name
  this.age = age
 }
 let res = myNew(Names, 'xiao', 2)
 console.log('res', res)

call的实现

在新对象内部创建一个 fn 函数,将 当前 this 赋值给 fn 函数
调用新对象中的 fn 函数执行
完成后将新对象中的 fn 函数删除(避免占用内存)

Function.prototype.call2 = function (obj, ...args) {
  if (typeof this !== 'function') {
     throw new TypeError('Error')
   }
   obj.fn = this;
   // 如果接收...args就不用下面这句,如果不接受参数需要获取参数
   // const args = [...arguments].slice(1) // 获取参数,第一个参数是this,从第二个开始
   let res = obj.fn(...args)
   delete obj.fn
   return res
 }

测试

var foo = {
    value: 1
 }
 function bar(name,age) {
     console.log('name',name);
     console.log('age',age);
 }
 bar.call2(foo,'susu',18);

大致思想一致:

apply的实现

改变 this 指向
传递一个参数数组
调用函数执行

Function.prototype.Myapply = function (context, arg) {
  context = context || window
   context.fn = this
   let res
   if(!arg) {
     result = context.fn()
   } else {
     result = context.fn(arg)
   }
   delete context.fn
   return result
 }

调用

function bar(...args) {
   console.log('...args',...args);
 }

 bar.Myapply(foo,['susu',18]);

Call/apply可以写成一样的,注意call和apply只有参数 不一样

 function myCall(context=window, ...args) {
      if(context !== 'object'){
        context = new Object(context)
      }
      let fn = Symbol()
      context.fn = this
      let res = context.fn(...args)
      delete context.fn
      return res
    }
function myApply(content=window, args) {
     if(content !== 'object'){
      content = new Object(content)
     }
     let fn = Symbol()
     content.fn = this
     let res = content.fn(...args)
     delete content.fn
     return res
   }

bind的实现

1.改变 this 指向;
2.接收多个参数;
3.返回一个新的函数

Function.prototype._bind = function (obj, ...args) {
  let self = this
   let fBound = function (...innerArgs) {
     return self.apply(this instanceof fBound ? this:obj, args.concat(innerArgs))
   }
   fBound.prototype = Object.create(this.prototype)
   return fBound
 }
function myBind(content) {

  let args = Array.prototype.slice.call(arguments,1)
  let that = this
  //简版
  // return function () {
  //   let innerArg = Array.prototype.slice.call(arguments)
  //   return that.apply(content,args.cancat(innerArg))
  // }
  //区别了new
  function Bind() {
    let innerArg = Array.prototype.slice(arguments)
    return that.apply(
      this instanceof that? this: content
      ,
      args.concat(innerArg)
    )
  }
  Bind.prototype = this.prototype
  return Bind
}

深拷贝

function deepCopy(obj) {
 if (typeof obj !== 'object' || obj == null) {
    return obj
  }
  let copy = Array.isArray(obj) ? [] : {}
  for (let key in obj) {
    if(obj.hasOwnProperty(key)){
      copy[key] = deepCopy(obj[key])
    }
  }
  return copy
 }

测试

let obj = { a: 1, b: { c: 2 } };
let copy = deepCopy(obj);
console.log(copy);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值