zoukankan      html  css  js  c++  java
  • Javascript中的bind

    引子:模拟bind函数

    实现一个$bind函数模拟bind函数。

    // no-log
    Function.prototype.$bind = function (obj) {
      let self = this
      return function () {
        self.apply(obj, arguments)
      }
    }
    

    下面进行测试

    // log
    let obj1 = { id: 0 }
    let obj2 = { id: 1 }
    function sayId() {
      console.log(this.id)
    }
    sayId.bind(obj1)() // ES5实现的bind
    sayId.$bind(obj2)() // 我们自定义的$bind
    

    很好,达到了我们想要的效果。

    有何不同

    然后探究我们的$bind和真实的bind有何差异。下面两部分代码分别使用了$bindbind,代码的其余部分完全相同,但是其输出却不同。

    // log
    function foo(something) {
      this.a = something
    }
    let obj1 = {}
    let fooWithBind = foo.$bind(obj1) // 这里不同
    let obj2 = new fooWithBind(999)
    
    console.log(obj1.a)
    console.log(obj2.a)
    
    // log
    function foo(something) {
      this.a = something
    }
    let obj1 = {}
    let fooWithBind = foo.bind(obj1) // 这里不同
    let obj2 = new fooWithBind(999)
    
    console.log(obj1.a)
    console.log(obj2.a)
    

    原因:ES5内置的bind更加复杂,主要体现在 this 的绑定的优先级上:它会判断硬绑定函数是否被new调用,如果是的话就会使用新创建的this代替硬绑定的this

    总结

    通过自定义一个残缺的bind函数,回顾了判断this指向的相关知识点。可按照如下步骤进行。

    1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。 如:var bar = new foo()
    2. 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是 指定的对象。 如:var bar = foo.call(obj2)
    3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上下文对象。如:var bar = obj1.foo()
    4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象 如:var bar = foo()

    参考

    [1]你不知道Javascript P94

  • 相关阅读:
    利用NPOI导出数据到Execl
    分享微信开发Html5轻游戏中的几个坑
    Integrate non-OSGi Dependencies
    Websocket Component
    ServiceMix in daemon mode
    springboot jwt配置(更新中)
    npm run build 后的dist文件,发布到web服务。
    不重复随机数列的生成算法 Leetcode 384. Shuffle an Array
    LSM树-HBASE为什么快
    混沌工程初探
  • 原文地址:https://www.cnblogs.com/oceans/p/13703190.html
Copyright © 2011-2022 走看看