• 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

  • 相关阅读:
    charles修改响应体
    charles重发网络请求&模拟慢速网络&过滤网络请求
    charles修改请求体内容
    monkeyrunner环境搭建以及实例(转)
    django模型中的抽象类(abstract)
    Linux启动/停止/重启Mysql数据库的方法
    ava.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind (解决思路)
    unix PS命令和JPS命令的区别
    mysql:表注释和字段注释
    mysql-关于Unix时间戳(unix_timestamp)
  • 原文地址:https://www.cnblogs.com/oceans/p/13703190.html
Copyright © 2020-2023  润新知