如何理解JavaScript this的指向

实习期间写代码时候就感觉this很迷。有些不知所措。后来查看了部分文章。

this最终指向的是调用它的对象(这个已经理解了大部分了)

  • 为什么要用this ? 为什么需要花费时间进行学习。

    答:this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将 API 设计 得更加简洁并且易于复用。随着你的使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用 this 则不会这样。

  • this的误区?

    • 不是指向自身
    • 第二种常见的误解是,this 指向函数的作用域 (分情况)
  • this是什么?

    this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调 用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

    当一个函数被调用的时候,会创建一个活动记录(有时候称为执行上下文)。这个记录会包含函数在哪里调用(调用栈)、函数的调用方法、传入的参数信息等。this就是记录的其中一个属性,会在函数执行过程中用到。

  • this到底是什么?

    this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用

  • 全面解析this

    1. 理解调用位置。调用位置就是函数在代码中被调用的 位置(而不是声明的位置)
      • 默认绑定

        独立函数调用。不带任何修饰的函数引用进行调用的,只能使用默认绑定。

      • 隐式绑定

        调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。

        // 第一个例字
        function foo() {    
            console.log( this.a );
        } 
         
        var obj = {    
            a: 2,    
            foo: foo  
        }; 
         
        obj.foo(); // 2
        
        // 第二个例子
        {
            
            let name = "sww_window";
            let obj = {
                "name":"sww",
                "fn":function(){
                    console.log(this.name);
                }
            }
            obj.fn(); // sww
            let obj1 = obj.fn;
            obj1(); //undefined
            
            // 将let name 更换成 var name
            obj(); //输出为sww_window 原因 let 默认不挂在window上面
            
        }
        
      • 显式绑定
        就是call apply bind call和apply只是参数不一样。bind 绑定了之后创建一个新的绑定函数。改变了this。
      • new绑定

        使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

        1. 创建(或者说构造)一个全新的对象。
        2. 这个新对象会被执行 [[ 原型 ]] 连接。
        3. 这个新对象会绑定到函数调用的 this。
        4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。

箭头函数中的this

在箭头函数内部,this 绑定不是 动态的,而是词法的。什么时候创建一个作用域!页面加载时候全局作用域 函数调用时候局部作用域。这个时候this已经确定了 调用者一般决定着this的走向。

上面是基本概念,比较虚的。直接上代码

代码环境:


image.png
//直接在暴露在全局
```javascript
  //直接在暴露在全局
  const aa = () => {
        console.log(this);
  };
  aa();
  // 执行出来之后就是 Window

这个很简单。this指向Window嘛。至于为什么 因为这个aa是全局变量(是定义在最外面的变量),可以这样理解,执行时候它被全局环境所包含。所以就是windows。不过不挂在window全局对象上面哈。(这里理解一下 let const 和 var的挂全局对象的区别哈)。

// 继续来一段: 
const bb = {
        aa: () => {
            console.log(this);
        },
        b: function () {
            this.aa();
        }
    };
   bb.b();
// 这里还是输出的Windows
// 继续来一段: 
const bb = {
        aa: function() {
            console.log(this);
        },
        b: function () {
            this.aa();
        }
    };
   bb.b();
// 这里输出的bb的这个对象

非箭头申明函数(普通函数)只有函数执行的时候才能确定this到底指向谁实际上this的最终指向的是那个调用它的对象

箭头函数是在函数在定义时,this就继承了定义函数的对象。 那么这个如何确定这个定义函数的this呢?还是从作用域。在当前作用域内this的指向。比如

const bb = {
        aa: () => {
            console.log(this);
        },
        b: function () {
            this.aa();
        }
  };
bb = {} 是一个块级作用域,访问对象时候(个人感觉也会确定一个上下文。
然后加载一些活动记录。this也在记录里面,又因为bb是全局变量。
所以就是this指向的就是Window)所以箭头函数指向的就是Window。

你可能感兴趣的:(如何理解JavaScript this的指向)