• js之this指向规则


    1.在浏览器环境中,this在全局作用域下指向window对象,nodejs里面指向global对象

    2.函数中三种不同的指向

    // 定义一个函数
    function foo() {
      console.log(this);
    }

    不同的环境指向不同的对象

    // 直接调用
    foo(); //window/global对象
    // 放在对象里使用
    let obj = {
      name:"why",
      foo:foo
    }
    obj.foo(); //obj对象
    // 通过call/apply调用
    foo.call("abc"); // String{"abc"}对象
    

    3.绑定方式

        3a 默认绑定,也就是独立的函数调用this或者函数作为参数传入另外一个函数,这时候this都是默认绑定的全局对象

    function test1() {
      console.log(this); // window
      test2();
    }
    
    function test2() {
      console.log(this); // window
      test3()
    }
    
    function test3() {
      console.log(this); // window
    }
    test1();

         3b 隐式调用,也就是某个对象发起的函数调用this。

    function foo() {
      console.log(this);
    }
    
    var obj1 = {
      name: "obj1",
      foo: foo
    }
    
    var obj2 = {
      name: "obj2",
      obj1: obj1
    }
    
    obj2.obj1.foo(); // obj1

         注意下面的调用方式是默认绑定

    var bar = obj1.foo;
    bar();

         3c 显示绑定

         也就是通过call和apply方法来绑定this。但是注意调用的对象内部有一个函数的引用,否则会报错

    function foo() {
      console.log(this);
    }
    
    foo.call(global); // 全局对象
    foo.call({name: "aaa"}); // {name: "aaa"}
    foo.call(123); // Number对象,存放是123
    

        bind函数(其实就是Function.prototype.bind)可以将一个函数显示绑定到一个对象上

    function foo() {
      console.log(this);
    }
    var obj = {
      name: "aaa"
    }
    var bar = foo.bind(obj);
    bar(); // obj对象
    bar(); // obj对象
    

        3d 特殊的内置函数

        在JS的一些内置函数里面,this指向会有一些不一样。

        setTimeout的函数参数里面的this指向的是全局对象,forEach默认下也是全局对象,但是可以传入第二参数来指定this绑定的对象。

        还有在Dom操作中,操作函数中的this指向的是节点对象

    var box = document.querySelector(".box");
    box.onclick = function() {
      console.log(this); // box对象
    }

          3e new关键字绑定

    使用new关键字调用函数时,创建的新对象会被执行prototype连接,然后绑定到函数调用的this上,如果函数没有返回其他对象,表达式会返回这个新对象。

    // 创建Person
    function Person(name) {
      console.log(this); // Person {}
      this.name = name;
    }
    
    var p = new Person("aaa");
    console.log(p); // Person {name: "aaa"}
    

    4 优先级

    默认绑定最低,显示大于隐式,new高于隐式和显示。

    5 其他情况

       5.1显示绑定时传入的是null或者undefined,那么这个显示绑定就被忽略使用默认绑定

       5.2 间接函数引用,使用默认绑定

             首先知道(num1=num2)的结果是num2

    function foo() {
      console.log(this);
    }
    var obj1 = {
      name: "obj1",
      foo: foo
    };
    var obj2 = {
      name: "obj2"
    }
    obj1.foo(); // obj1对象
    // ()里面的结果是foo函数
    (obj2.foo = obj1.foo)();  // window/global

        5.3 箭头函数

       箭头函数没有作用域,不使用上述规则,而是根据外层作用域来决定this的指向

    几个面试题地址:https://mp.weixin.qq.com/s/hYm0JgBI25grNG_2sCRlTA

  • 相关阅读:
    LeetCode 75. Sort Colors(按颜色进行排序)
    LeetCode 451. Sort Characters By Frequency(按照字符出现次数对字符串排序)
    LeetCode 347. Top K Frequent Elements(出现频率最多的 k 个元素)
    LeetCode 215. Kth Largest Element in an Array(数组求第k大)
    CF #629 Div.3 E(LCA)F
    系统函数
    CASE表达式
    循环得出数据库中所有的 DB_ID,DB_NAME
    数据库的编码问题
    检验临时表是否存在
  • 原文地址:https://www.cnblogs.com/haoqirui/p/13709109.html
Copyright © 2020-2023  润新知