【JS基础系列】如何正确判断this的指向?

【JS基础系列】如何正确判断this的指向?_第1张图片
JS基础面试基础.jpeg

首先我们要清楚this的指向确定是发生在调用的时候的,而不是声明this的时候。

this的指向总共可以分为五种:

默认绑定(非严格模式-window,严格模式-undefined)

隐式绑定(一般是上下文,特殊情况指向window或者undefined)

显式绑定(指向绑定的对象,特殊情况指向window或者undefined)

new绑定(一般指向新对象,但是返回function或object时,指向返回的对象)

箭头函数绑定(指向上下文中的this)

1.默认绑定的 this

  • 浏览器环境:
    无论是否在严格模式下,在全局执行环境中(在任何函数体外部this 都指向全局对象 window;
  • node 环境:
    无论是否在严格模式下,在全局执行环境中(在任何函数体外部),this 都是空对象 {}

非严格模式下,this在普通函数中被调用,this会指向全局的window。

// 非严格模式下
function func() {
    console.log(this);
}
func();  // window

严格模式下,this在普通函数中被调用,this会指向undefined。

// 严格模式下
function func() {
    "use strict";
    console.log(this);
}
func();  // undefined

2.隐式绑定的this

当函数引用有上下文对象时,隐式绑定规则会把函数中的this绑定到这个上下文对象。对象属性引用链中只有上一层或者说最后一层在调用中起作用,this指向了这个上下文对象。典型的隐式调用为: xxx.fn()

function func() {
    console.log(this.a);
}
var a = 5;
var obj = {
    a: 10,
    func: func
}
obj.func();  // 10

但是在隐式绑定某些情况下的this会指向window或者undefined。(即类似默认绑定)

function func() {
    console.log(this.a);
}
var a = 5;
var obj = {
    a: 10,
    func: func
}
var func1 = obj.func;
obj.func();  // 10
// func1在调用的时候没有绑定到任何的上下文对象中,所以应用的是默认绑定。
func1();  // 5

3.显式绑定的this

call,apply,bind 绑定中,this指向的就是绑定的对象【称为硬绑定】。这里同样需要注意一种特殊情况,如果call,apply或者bind 传入的第一个参数值是 undefined 或者 null,那么这些值在调用时会被忽略,实际应用的是默认绑定规则。

function info(){
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
var info = person.info;
info.call(person);   //20
info.apply(person);  //20
info.bind(person)(); //20

当第一个参数为null和undefined时,this指向全局对象。这个时候严格模式下 this 的值为传入的值 null /undefined,非严格模式为全局对象(node环境为global,浏览器环境为window)

4.new 绑定-构造函数中的this

如果是 new 绑定,并且构造函数中没有返回 function 或者是 object,那么 this 指向这个新对象。如下:

构造函数返回值不是 function 或 object。

function Super(age) {
    this.age = age;
}
let instance = new Super('26');
console.log(instance.age); //2

构造函数返回值是 function 或 object,这种情况下 this 指向的是返回的对象。

function Super(age) {
    this.age = age;
    let obj = {a: '2'};
    return obj;
}
let instance = new Super('hello');
console.log(instance.age); //undefined

你可以想知道为什么会这样?我们来看一下 new 的实现原理:

  • 创建一个新对象。
  • 这个新对象会被执行[[原型]]连接。
  • 属性和方法被加入到 this 引用的对象中。并执行了构造函数中的方法.
  • 如果函数没有返回其他对象,那么this指向这个新对象,否则this指向构造函数中返回的对象。
function new(func) {
    let target = {};
    target.__proto__ = func.prototype;
    let res = func.call(target);
    //排除 null 的情况
    if (res && typeof(res) == "object" || typeof(res) == "function") {
      return res;
    }
    return target;
}

5.箭头函数中的this

箭头函数有两个方面的作用:更简短的函数并且不绑定this。
箭头函数没有自己的this,继承外层上下文绑定的this。

var a = 20;
function func() {
    var a = 10;
    return () => {
        console.log(this.a)
    }
}

var func1 = func();
func1();  // 20 箭头会从它的上一层func继承this,上一层的this是window,所以是20。如果上一层是箭头函数那会继续往上找。

另一个例子

let obj = {
    age: 20,
    info: function() {
        return () => {
            console.log(this.age); //this继承的是外层上下文绑定的this
        }
    }
}

let person = {age: 28};
let info = obj.info();
info(); //20

let info2 = obj.info.call(person);
info2(); //28

恭喜你,又掌握了一个新技能~
喜欢就点个关注吧~❤️
关注微信公众号【前端FE】了解更多

【JS基础系列】如何正确判断this的指向?_第2张图片
公众号:【前端FE】.PNG

你可能感兴趣的:(【JS基础系列】如何正确判断this的指向?)