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

  • 相关阅读:
    A.4.2虚函数 virtual 和多态的实现
    A.51,集合类 ArrayList。2,对字符串的处理(String)
    A.4.1类的继承(implement)
    Android ExpandableListView的使用
    Android 使用SAX解析XML
    [转]Android 内存监测工具 DDMS > Heap .
    Android中 ExpandableList的使用2
    Android 横屏竖屏的切换
    Android 文件操作
    Android Preference的使用总结(很全很详细)以及SharedPreferences多个程序之间共享数据
  • 原文地址:https://www.cnblogs.com/oceans/p/13703190.html
Copyright © 2011-2022 走看看