• this指哪去了


    前言

    但凡是前端的人应该都被this折磨过,不管是不会用还是用错都会造成很大的麻烦,不论是敲代码还是准备面试时候,都要复习好多次,这次记个笔记方便以后复习。

    this的特点

    官方解释:this 被自动定义在所有函数的作用域中,它提供了一种更好的方式来“隐式”的传递对象引用,这样使得我们的 API 设计或者函数变得更加简洁,而且还更容易复用。

    简单的来讲就是为了在函数作用域内更方便的使用这个函数中的对象内容
    例1:
    在这里插入图片描述

    这里的this就指向的是整体的类中,通过this可以访问类中的内容

    例2:
    在这里插入图片描述

    person1person2是两个对象想用一个函数就动态的输出两个对象对应的值。
    没有this之前可能想的是给say方法传递参数,但通过this.可以直接通过this.name,然后改变this的指向(call就是用来改变内容this的指向的)

    上面这些可以让你很清晰的理解到this是干什莫的。

    但是他this的难点不在这里。难点在于this指向的是什么地方。

    this 就是一个对象,this 是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

    常见的this指向
    1.普通函数:指向window

    在直接定义的普通函数中使用时,this指向的是window层面

    let x = 1;
    var y = 2;
    function f(){
        console.log(this.x) 
        console.log(this.y) 
    }
    f();
    //打印 :undefined
    //2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    首先f的执行环境为window,所以this指向windowthis.xthis.y等同于window.xwindow.y

    那为什么this.x不是1呢?

    var声明的y变量会被js引擎挂在到jswindow属性中,所以window.y是2。然而es6let声明的变量,不会被挂载到window属性中,而是会挂载到和Global(window)同级的Script中。this.x还是等同于window.x,但是由于window上没有x这个属性,所以就打印undefined了。、

    2.对象方法:指向调用该方法的对象

    根据该方法调用时所处的环境,决定指向

    let obj1 ={
        x:1,
        f:function(){
            console.log(this.x)
        }
    }
    let obj2 ={
        x:2,
        f:obj1.f
    }
    obj1.f() //1
    obj2.f()//2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    第一个函数f在``obj1环境下执行,this指向obj1,所以this.x等同于obj1.x`,打印1。

    我相信第一个大家都没问题,第二个就有点疑惑了,有人可能会这样想:obj2.f明明是调用obj1.ff的运行环境还在obj1中,应该打印1才是。
    但是现在调用的这个方法上层是在obj2的环境中,指向的实际上是obj2的内容

    因此,对象方法中this指向调用该方法的对象。注意:

    如果我们调用函数时有多个引用调用,比如obj1.obj2.foo()。这个时候函数 foo 中的 this 指向哪儿呢?其实不管引用链多长,this 的绑定都由最顶层调用位置确定,即obj1.obj2.foo()this 还是绑定带 obj2

    如果我们调用函数时有多个引用调用,比如obj1.obj2.foo()。这个时候函数 foo 中的 this 指向哪儿呢?其实不管引用链多长,this 的绑定都由最顶层调用位置确定,即obj1.obj2.foo()this 还是绑定带 obj1


    作者:小猪课堂
    链接:https://juejin.cn/post/7115390077353590792
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    3.构造函数:指向实例对象

    function F(x){
        this.x=x
        this.f=function(){
            console.log(this.x)
        }
    }
    let fn = new F(2)
    fn.f()//2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里的this指向具体的实例对象,也就是fnfn中存在x属性:2,this.x也就是fn.x,输出2了。

    4.绑定事件函数 :指向绑定事件的元素
    
    const btn = document.querySelector("button");
          btn.onclick = function () {
            console.log(this);
          };
    //打印
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    5.回调函数

    对于回调函数中的this对象。对于普通函数,this指向调用时所在的对象(即window对象)。对于箭头函数,this指向定义生效时所在的对象。

    普通函数:

    var id = 10;
    function foo() {
         setTimeout(function () {
             console.log(this.id);
        }, 1000);
    }
    foo(); //10
    foo.call({ id: 30 }); //10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上面都输出10,this指向window对象,原因是1s后,回调函数执行,此时回调函数所在对象为window

    箭头函数

    对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。

    var id = 10;
    function foo() {
         setTimeout(()=> {
            console.log(this.id);
        }, 1000);
    }
    foo();//10
    foo.call({ id: 30 });//30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第一个回调函数输出10,定义时this就已经确认了指向,指向window

    第二个回调函数输出30,与上述不同的是,这个回调函数的this在定义时已经重新指向为{id:30}这个对象了。

    6.立即调用函数 :window
    (function(){console.log(this)})() //window
    
    • 1
    注意严格模式下this
    "use strict";
     console.log(this); //window
     function f() {
         console.log(this); //undefined
     }
     f();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 在严格模式下,在全局作用域中,this指向window对象
    • 在严格模式下,全局作用域函数中this等于undefined
  • 相关阅读:
    第十三章第一节:Java数据结构预备知识之数据结构、Java集合框架概述
    javascript复习之旅 2.2 typeof
    1033 To Fill or Not to Fill
    R语言layout () 函数
    【Android笔记29】Android中的数据存储技术之内部存储、外部存储
    SpringBoot-36-分布式理论概述
    Android shell 常用 debug 命令
    [Spring笔记] Spring-35-AOP通知获取数据
    【Spring Cloud】openfeign负载均衡方案(和lb发展历史)
    ndk-build
  • 原文地址:https://blog.csdn.net/qq_53145332/article/details/126689086