• this的四个绑定规则


    this指向

    • 全局作用域下的this指向window
    • 如果给元素的事件行为绑定函数,那么函数中的this指向当前被绑定的那个元素
    • 函数中的this,要看函数执行前有没有., 有.的话,点前面是谁,this就指向谁,如果没有点,指向window
    • 自执行函数中的this永远指向window
    • 定时器中函数的this指向window
    • 构造函数中的this指向当前的实例
    • call、apply、bind可以改变函数的this指向
    • 箭头函数中没有this,如果输出this,就会输出箭头函数定义时所在的作用域中的this

    this的四个绑定规则

    1、默认绑定

    规则:非严格模式默认指向window,严格模式指向undefined。

    最常用的函数调用类型:独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则。

    • 不带任何修饰的函数引用进行调用(独立函数调用),指向window。
    function foo() {console.log(this.a)
    }
    var a = 2
    foo() // 2 
    

    解析:foo() 是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则foo属于独立函数调用的,触发了默认绑定,从而指向全局window

    • 函数调用链(一个函数又调用另外一个函数)
    • 将函数作为参数,传入到另一个函数中,作为函数的参数,指向window

    2、隐式绑定

    隐式绑定的 this,指向调用函数的上下文对象

    2.1 一般的对象调用

    规则:会把函数调用中的 this 绑定到这个上下文对象

    function foo() {console.log(this.a)
    }
    
    const obj = {a: 2,foo: foo
    }
    
    // 通过 obj 对象调用 foo 函数
    obj.foo() // 2 
    
    2.2 对象属性引用链

    规则:对象属性引用链中只有上一层或者说最后一层在调用位置中起作用。

    function foo() {console.log(this.a)
    }
    
    var obj2 = {a: 2,foo: foo
    }
    
    var obj1 = {a: 1,obj2: obj2
    }
    
    obj1.obj2.foo() // 2 
    
    2.3 隐式绑定丢失问题
    • ①将对象里的函数赋值给一个变量
    function foo() {console.log(this.a)
    }
    
    var obj = {a: 2,foo: foo
    }
    
    var bar = obj.foo // 函数别名!
    
    var a = 'global' // a 是全局对象的属性
    bar() // "global" 
    

    虽然 barobj.foo 的一个引用,但是实际上,它引用的是 foo 函数本身,因此此时的 bar() 其实是一个不带任何修饰的函数调用,因此应用了默认绑定

    • ②传入回调函数时
    function foo() {console.log(this.a)
    }
    
    function doFoo(fn) {// fn 其实引用的是 foofn() // <-- 调用位置!
    }
    var obj = {a: 2,foo: foo
    }
    var a = 'global'// a 是全局对象的属性
    doFoo(obj.foo)// "global" 
    

    参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值,所以结果和上一 个例子一样。

    3、显式绑定

    直接指定 this 的绑定对象,因此我们称之为显式绑定

    3.1 使用 call(…) 和 apply(…)

    如果我们不想在对象内部包含函数引用,而想在某个对象上强制调用函数,该怎么做呢? 可以使用函数的 call(..)apply(..) 方法

    JavaScript 提供的绝大多数函数以及你自 己创建的所有函数都可以使用 call(..)apply(..) 方法。

    function foo() {console.log(this.a)
    }
    var obj = {a: 2
    }
    foo.call(obj) // 2 
    
    3.2 硬绑定-bind

    硬绑定是指一个函数总是显示的绑定到一个对象上

    由于硬绑定是一种非常常用的模式,所以 ES5 提供了内置的方法 Function.prototype.bind, 它的用法如下

    function foo(num) {console.log(this.a, num)return this.a + num
    }
    
    var obj = {
    a: 2
    }
    // 调用 bind() 方法,返回一个函数,那么这个新函数的 `this`,永远指向我们传入的`obj`
  • 相关阅读:
    0 算法复杂度
    js 找出两个数组中的重复元素
    资金核对平台的发展历程
    docker 中给命令起别名
    React Hooks解析
    扬帆际海—移动端流量对跨境电商有多重要?
    OSG3.6.5帮助文件档编译
    【毕业设计】基于php+mysql+apache的subversion用户管理系统设计与实现(毕业论文+程序源码)——用户管理系统
    1.2 w字+!Java IO 基础知识系统总结 | JavaGuide
    【LeetCode-中等题】116. 填充每个节点的下一个右侧节点指针
  • 原文地址:https://blog.csdn.net/web220507/article/details/127093279