• javascript 中的 this 判定


    this 关键字是 JavaScript 中比较复杂的机制之一,它是一个很特别的关键字,被自动定义在所有函数的作用域中。人们很容易把 this 理解成指向函数自身,这其实是不对的。每个函数的 this 是在调用时被绑定的,取决于函数的调用位置。

    绑定规则

    默认绑定

    这是最常用的函数调用类型即独立函数调用,当无法应用其他规则时,便走这条默认规则。此时 this 会被绑定到全局对象,严格模式下会被绑定到 undefined 。

    首先我们来看下面这段代码

    function test() {
      console.log(this.a);
    }
    
    var a = 2;
    
    test(); // 2

    我们可以看到当 test 函数被调用时,this.a 指向了我们定义的全局变量 a。这里 test 函数是独立函数的调用,应用的是默认绑定的规则,此时 this 指向全局对象。

    我们再来看看使用严格模式时的运行情况

    function test() {
      'use strict';
      console.log(this.a);
    }
    
    var a = 2;
    
    test(); // TypeError: Cannot read property 'a' of undefined

    可以看到,在严格模式下,this 将会绑定到 undefined。

    隐式绑定

    这条规则是要考虑调用位置是否有上下文对象。此时 this 被绑定到这个上下文对象上面。

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 2,
      test: test
    };
    
    obj.test(); // 2

    可以看到 test 函数是使用 obj 这个上下文对象来调用的,此时 this 会绑定到 obj 这个上下文对象,this.a 其实就是 obj.a 都是 2。

    显式绑定

    显式绑定是指我们通过 call 、apply 方法强制改变函数运行时的上下文对象。它们的第一个参数是一个对象,函数调用时 this 就会绑定到这个对象上面。

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 2
    };
    
    test.call(obj); // 2

    我们通过 test.call(obj) 强制把 this 绑定到 obj 上。这里我们想一下,如果把 null、undefined 作为 this 的绑定对象传入会怎么样呢?

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 2
    };
    
    var a = 1;
    
    test.call(null); // 1
    
    test.call(undefined); // 1

    可以看到,当显示绑定到 null、undefined 时,这些值在函数调用时会被忽略,此时会使用默认规则来绑定 this 到全局对象。

    new 绑定

    我们首先先要了解下通过 new 来调用函数,发生了哪些步骤。

    1. 创建一个全新的对象

    2. 新对象会被执行原型连接

    3. 新对象会绑定到函数调用的 this

    4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象

    我们看下面代码

    function Test (a) {
      this.a = a;
    }
    
    var test = new Test(2);
    
    test.a // 2

    使用 new 来调用函数 Test 时,会创建一个新的对象并且把它绑定到 Test 调用中的 this 上。

    优先级

    我们已经知道了 this 指向的 4 条规则,那么当一个函数调用时同时满足多条规则时该怎么办呢?这时候我们确定这 4 条规则的优先级。

    记住: new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定。

    所以我们可以按照下列顺序来判断 this 指向:

    1. new 绑定:函数是否是通过 new 调用的?如果是那么 this 绑定的就是新创建的对象。

    2. 显式绑定:函数是否通过 call、apply 调用的?如果是那么 this 绑定的就是指定的对象。

    3. 隐式绑定:函数是否在某个上下文对象中调用?如果是那么 this 绑定的就是那个上下文对象。

    4. 默认绑定:如果以上都不是的话,使用默认绑定。this 绑定到全局对象上,注意如果在严格模式下,this 会绑定到 undefined 上。

    值得一提的是,ES6 中的箭头函数并不会使用以上四条绑定规则,箭头函数会继承外层函数调用的 this 绑定。其实和 ES6之前代码中的 var self = this 机制一样。

    更多精彩内容,欢迎关注微信公众号~

  • 相关阅读:
    Java类的三大特征
    java语句
    Python数据类型深入学习之数字
    Python基础学习篇章四
    Python基础学习篇章三
    Python基础学习篇章二
    python基础学习篇章一
    项目中调用天气预报接口
    CI框架传递数组到view层问题记录
    记录使用CI框架开发项目时遇到的问题
  • 原文地址:https://www.cnblogs.com/alsy/p/12245713.html
Copyright © 2020-2023  润新知