JS回归基础之this

最近看了很多篇关于this的文章,总结一下吧,这样才能印象深刻。
函数的this在调用时绑定的,完全取决于函数的调用位置(也就是函数的调用方法)。为了搞清楚this的指向是什么,必须知道相关函数是如何调用的。

全局上下文

非严格模式和严格模式中this都是指向顶层对象(严格模式下顶层对象为undefined,非严格模式下顶层对象浏览器中是window,node的顶层对象是global对象)

this === window // true

函数上下文

  1. 普通函数调用模式
  2. 对象中的函数(方法)调用模式
  3. call、apply、bind 调用模式
  4. 构造函数调用模式
  5. 原型链中的调用模式
  6. 箭头函数调用模式
  7. DOM事件处理函数调用

有常见上面几种方式,下面一条条解释
普通函数调用模式

// demo01
var a = 20;
function fn() {
  console.log(this.a);
}
fn();

打印20,非严格模式自动指向window

// demo02
var a = 20;
function fn() {
  function foo() {
    console.log(this.a);
  }
  foo();
}
fn();

打印20,非严格模式自动指向window

如果函数独立调用,那么该函数内部的this,则指向undefined。
在非严格模式中,当this指向undefined时,它会被自动指向全局对象,严格模式下指向undefined。

对象中的函数(方法)调用模式

// demo03
var a = 20;
var obj = {
  a: 10,
  c: this.a + 20,
  fn: function () {
    return this.a;
  }
}

console.log(obj.c);
console.log(obj.fn());

打印40 10,指向obj
如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。

call、apply、bind 调用模式

function fn(num1, num2) {
  console.log(this.a + num1 + num2);
}
var obj = {
  a: 20
}

fn.call(obj, 100, 10); // 130
fn.apply(obj, [20, 10]); // 50

构造函数调用模式

function Student(name){
    this.name = name;
    console.log(this); // {name: '若川'}
    // 相当于返回了
    // return this;
}
var result = new Student('若川');

使用new操作符调用函数,会自动执行以下步骤。

  1. 创建一个新对象
  2. 构造函数的this指向该对象
  3. 指向构造函数的代码,为这个对象添加属性,方法等;
  4. 返回新对象

原型链中的调用模式

function Student(name){
    this.name = name;
}
var s1 = new Student('若川');
Student.prototype.doSth = function(){
    console.log(this.name);
}
s1.doSth(); // '若川'

箭头函数调用模式

var name = 'window';
var student = {
    name: '若川',
    doSth: function(){
        // var self = this;
        var arrowDoSth = () => {
            // console.log(self.name);
            console.log(this.name);
        }
        arrowDoSth();
    },
    arrowDoSth2: () => {
        console.log(this.name);
    }
}
student.doSth(); // '若川'
student.arrowDoSth2(); // 'window'

箭头函数中没有this绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象
DOM事件处理函数调用

总结

如果要判断一个运行中函数的 this 绑定, 就需要找到这个函数的直接调用位置

  1. 普通函数调用: 在严格模式下绑定到 undefined,否则绑定到全局对象。
  2. new 调用:绑定到新创建的对象,注意:显示return函数或对象,返回值不是新创建的对象,而是显式返回的函数或对象。
  3. call 或者 apply( 或者 bind) 调用:严格模式下,绑定到指定的第一个参数。非严格模式下,null和undefined,指向全局对象(浏览器中是window),其余值指向被new Object()包装的对象。
  4. 对象上的函数调用:绑定到那个对象。
  5. 箭头函数没有this,会根据作用域链寻找上一个普通函数的this

希望大家看完后多参考几篇文章,最后自己一定要总结一遍,梳理思路,这样才会印象深刻,不要模棱两可。

参考:
https://juejin.cn/post/6844903746984476686#heading-4
https://www.jianshu.com/p/d647aa6d1ae6

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值