JavaScript

🌸 您好,欢迎您的阅读,等君久矣,愿与君畅谈.
🔭 § 始于颜值 § 陷于才华 § 忠于人品 §
📫 希望我们可以进一步交流,共同学习,共同探索未知的技术世界 稀土掘金 OR GitHub.


# 函数的 this 绑定
  1. 全局作用域下

    1. 浏览器环境:全局作用域下 this 绑定 window

    2. node 环境: 空对象{}

      1. 执行步骤:首先将要执行的 js 文件作为模块,然后进行加载编译,此时将 js 代码所有文件放入一个函数中,执行该函数,但是该函数调用 call() , 在调用时向 call() 中传入一个空对象绑定为 this执行函数.call({})
  2. 函数作用域下 this 指向

    1. 函数在被调用时,JavaScript 会默认给 this 绑定一个值,this 指向与函数所处位置 (函数定义位置) 无关,与函数被调用的方式及调用位置有关,this 是在运行时被绑定

    2. 默认绑定

      1. 独立函数调用 this 指向的是全局对象 window

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        function foo() {
        console.log(this);
        }
        var obj1 = {
        name: "obj1",
        foo: foo
        }
        // 将obj1的foo赋值给bar
        var bar = obj1.foo;
        bar();
    3. 隐式绑定

      1. 通过某个对象进行调用,即调用位置中是通过某个对象发起的函数调用 (谁发起函数调用 this 就绑定谁)

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        function foo() {
        console.log(this);
        }
        var test = {
        name: "test",
        foo: foo
        }
        var obj1 = {
        name: "obj1",
        test: test
        }
        var obj2 = {
        name: "obj2",
        obj1: obj1
        }
        obj2.obj1.test.foo();//test对象
      2. object.fn() :object 对象会被 js 引擎绑定到 fn 函数中的 this 上

      3. 隐式绑定的前提条件

        1. 必须在调用的对象内部有一个对函数的引用(比如一个属性)
        2. 如果没有这样的引用,在进行调用时,会报找不到该函数的错误
        3. 正是通过这个引用,间接的将 this 绑定到了这个对象上
    4. 显示绑定

      1. call()

        1. 第一个参数为绑定对象,第二个参数为参数列表 (剩余参数形式)
      2. apply()

        1. 第一个参数为绑定对象,第二个参数为参数列表 (数组形式)
        1
        2
        3
        4
        5
        function sum(num1,num2,num3) {
        console.log(num1+num2+num3,this);
        }
        sum.call("call",20,30,40);//剩余参数形式
        sum.apply("apply",[20,30,40]);//数组形式
      3. bind()

        1. 第一个参数为绑定对象,第二个参数为参数列表 (剩余参数形式), bind 返回为一个新的函数
        1
        2
        3
        4
        5
        6
        function foo() {
        console.log(this);
        }
        // 默认绑定和显示绑定bind冲突:优先级(显示绑定)
        var newFoo = foo.bind("aaaa");
        newFoo();
    5. new 绑定

      1. 使用 new 关键字来调用函数执行如下的操作
        1. 创建一个全新的对象,并将该对象赋值给 this,函数最后返回该对象
        2. 这个新对象会被执行 prototype 连接
        3. 这个新对象会绑定到函数调用的 this 上(this 的绑定在这个步骤完成)
        4. 如果函数没有返回其他对象,表达式会返回这个新对象
    6. 内置函数绑定

      1. setTimeout

        1
        2
        3
        4
        // 因为setTimeout内部实现函数调用时为独立函数调用,所以打印this时指向window
        setTimeout(function (){
        console.log(this); //window
        }, 2000);
      2. 数组.forEach/map/filter/find等高阶函数

        1
        2
        3
        4
        5
        6
        7
        8
        9
        var names = ["aaa","bbb","ccc","ddd"];
        // 函数直接独立调用指向window
        names.forEach(function (item) {
        console.log(item,this);
        })
        // forEach函数接收两个参数,第一个参数为一个函数,第二个参数为this绑定对象
        names.forEach(function (item) {
        console.log(item,this);
        },"forEach")
      3. div的点击

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        // 2、监听box盒子的点击,内部函数调用实现为:隐式this绑定调用进行打印即boxDiv.onclick()形式调用
        const boxDiv = document.querySelector(".box");
        // 1.方式一:该方式添加监听事件会进行覆盖,也就是后面一个监听事件会覆盖前面一个,只生效一个最后一个事件
        boxDiv.onclick = function () {
        console.log(this);
        }
        // 2.方式二:不会进行事件覆盖,会将函数收集到一个数组里面,执行时进行遍历
        // 内部函数调用实现为:call()方式,即fn.call(boxDiv)
        boxDiv.addEventListener("click",function () {
        console.log(this);
        })
        boxDiv.addEventListener("click",function () {
        console.log(this);
        })
        boxDiv.addEventListener("click",function () {
        console.log(this);
        })

JavaScript
http://example.com/2022/06/15/4001_JavaScript/
作者
XGG
发布于
2022年6月15日
更新于
2023年6月3日
许可协议