最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript手写系列总结

    正文概述 掘金(linlei)   2021-04-14   482

    new

    实现原理:

    • 创建一个空对象
    • 创建的对象的__proto__指向构造函数的原型对象
    • 执行这个函数,并将创建的对象作为this的上下文
    • 如果改函数没有返回对象,则返回this
    function myNew(fn,...args) {
        const obj = Object.create(null)
        obj.__proto__ = obj.prototype
        const result = fn.apply(obj, args)
        const isObject = typeof result === 'object' && result !== null 
        const isFunction = typeof result === 'function'
        if(isObject || isFunction) return result
        return obj
    }
    
    测试
    function P() {
        const args = Array.prototype.slice.call(arguments, 0)
        console.log(args)
    }
    var p = myNew(P, 1,2,3)
    var p2 = new p(1,2,3)
    
    结果

    JavaScript手写系列总结

    call,apply

    call和apply实现思路一样区别就是传入的参数call是展开参数,apply是数组先看实现步骤:

    1. 改变上下文this的指向
    2. 执行这个函数
    3. 并返回运行结果

    call

    Function.prototype.myCall = function(context,...args) {
        if(typeof this!=='function') {
            throw new TypeError('not function')
        } 
        context = context || window
        context.fn = this
        const result = context.fn(...args)
        delete context.fn
        return result
    }
    
    测试
    function p(...args) {
            console.log(...args,this.a)
    }
    const obj = {
            a: 2
    }
    p.myCall(obj,  1)
    p.call(obj,  1)
    
    结果

    JavaScript手写系列总结

    apply

    Function.prototype.myApply = function(context,args) {
        if(typeof this!=='function') {
            throw new TypeError('not function')
        } 
        context = context || window
        context.fn = this
        const result = context.fn(...args)
        delete context.fn
        return result
    }
    
    测试
    function p(...args) {
            console.log(...args,this.a)
    }
    const obj = {
            a: 2
    }
    p.myApply(obj,  [1,3])
    p.apply(obj,  [1,3])
    
    结果

    JavaScript手写系列总结

    bind

    实现原理:创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

    Function.prototype.myBind = function() {
        if (typeof this !== 'function') {
          throw new TypeError('not function');
        }
        var slice = Array.prototype.slice;
        var thatFunc = this, // function p
        thatArg = arguments[0]; // 获取传入的对象也就是上下文
        var args = slice.call(arguments, 1); // 获取传入的参数
        return function(){
          var funcArgs = args.concat(slice.call(arguments)) // 合并参数
          return thatFunc.apply(thatArg, funcArgs);  // 使用apply进行调用
        };
      };
    
    测试
      function p() {
          console.log(this)
      }
      const obj = {
          a: 1
      }
        p.bind(obj)()
        p.myBind(obj)()
    
    结果

    JavaScript手写系列总结

    instanceof

    原理:判断某个对象是否属于某个类型,或者是该类型的父类型祖先类型。

    function myInstanceof(left, right) {
        let leftValue = left.__proto__
        let rightValue = right.prototype
        while(leftValue) {
          if(leftValue===rightValue) {
            return true
          }
          leftValue = leftValue.__proto__
        }
        return false
      }
    
    测试
    function P() {}
    const p = new P()
    console.log(p instanceof P)
    console.log(myInstanceof(p, P))
    
    结果

    JavaScript手写系列总结

    Promise.all

    核心思路

    1. 接收一个Promise实例的数组或者具有Iterator接口的对象作为参数
    2. 这个方法返回一个新的Promsie对象
    3. 遍历传入的参数,用Promsie.resolve()将参数进行包裹使其变成一个Promsie对象
    4. 参数所有回调成功才是成功,返回值数组与参数顺序一致,参数数组只要有一个失败则触发失败状态
     function promiseAll(promsies) {
        return new Promise((resolve, reject)=> {
          if(!Array.isArray(promsies)) {
            throw new Error('not Array')
          }
          let len = promsies.length
          let count = 0
          let result = []
          for(let i=0;i<len;i++) {
            Promise.resolve(promsies[i]).then(data=> {
              result.push(data)
              count++
              if(count===len) {
                return resolve(result)
              }
            }).catch(err=> {
              return reject(err)
            })
          }
        })
      }
    
    测试
    const p1 = Promise.resolve(1)
      const p2 = Promise.resolve(2)
      Promise.all([p1, p2]).then(data=> {
          console.log(data)
      })
      promiseAll([p1, p2]).then(data=> {
          console.log(data)
      })
    
    结果

    resolve态 JavaScript手写系列总结 reject态

    JavaScript手写系列总结

    Array.map, Array.filter

    map和filter就太简单了

    map

    Array.prototype.myMap = function(cb, thisArgs) {
      let i = 0
      let len = this.length
      let result = []
      while(i<len) {
        let cbResult = cb.call(thisArgs, this[i], index, this)
        result.push(cbResult)
        i++
      }
      return result
    }
    
    测试
    let arr = [1,2,3]
    
    let newArr1 = arr.myMap((item)=> {
           return item * 2
    })
    let newArr2 = arr.map((item)=> {
           return item * 2
    })
    console.log(newArr1)
    console.log(newArr2)
    
    结果

    JavaScript手写系列总结

    filter

    Array.prototype.myFilter = function(cb, thisArgs) {
      let i = 0
      let len = this.length
      let result = []
      while(i<len) {
        let cbResult = cb.call(thisArgs, this[i], i, this)
    //     result.push(cbResult)
    cbResult && result.push(this[i])
        i++
      }
      return result
    }
    
    测试
    let arr = [1,2,3]
    
    let newArr1 = arr.myFilter((item)=> {
           return item > 1
    })
    let newArr2 = arr.filter((item)=> {
           return item > 1
    })
    console.log(newArr1)
    console.log(newArr2)
    
    结果

    JavaScript手写系列总结


    起源地下载网 » JavaScript手写系列总结

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元