【面试】JS中的this指向问题

0、总结:

在这里插入图片描述

1、是什么?

this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用。
this的指向在函数定义的时候是无法确定的,只有函数执行的时候才能确定this指向谁。实际上this指向调用它的对象

2、普通函数

2.1 非严格模式下,this指向window

    function a() {
    
    
      console.log(this); 
    }
    a() // window

2.1 严格模式下,this指向undefined

注意:严格模式"use strict"要写到函数内部才会起效,写在函数外部依然指向window

    function a() {
    
    
      "use strict";
      console.log(this);
    }
    a();

3、call apply bind

这三个方法都可以改变函数的this指向,除了箭头函数以外,箭头函数的this指向无法改变,这个问题在后续详细说。

面试题:三者的区别是什么?
回答:
1、三者都可以改变函数的this对象指向;
2、三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局window;
3、三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入;
4、bind是返回绑定this之后的函数,需要自己再执行。而apply、call 则是立即执行。

3.1 不传参 / 传入null或者undefined,指向window

    function fn() {
    
    
      console.log(this);
    }
    fn.call();						// window
    fn.apply(null);					// window
    let res = fn.bind(undefined);	
    res(); // bind返回一个函数,需要调用		//window

输出结果:
在这里插入图片描述

3.2 传参,指向传入的内容

    function fn2() {
    
    
      console.log(this);
    }
    fn2.call({
    
     x: 101 });   // {x: 101}
    fn2.apply("abc");       // String {'abc'}
    fn2.apply(123);         // Number {123}
    let fn = fn2.bind({
    
     name: "admin" });
    fn();                   // {name: 'admin'}

输出内容:
在这里插入图片描述

3.3 call() 和 apply() 的区别

第一个参数都是this的指向,
call 后面传入参数是一个参数列表,需要用逗号隔开
apply 第二个参数是函数接收的参数,以数组的形式传入
示例:
call():

function fn(...args){
    
    
    console.log(this,args);
}
let obj = {
    
    
    myname:"张三"
}

fn.call(obj,1,2); // 传入的参数用逗号隔开;

apply():

function fn(...args){
    
    
    console.log(this,args);
}
let obj = {
    
    
    myname:"张三"
}

fn.apply(obj,[1,2]); // 传入的参数必须是一个数组;

均输出为:
在这里插入图片描述

4、定时器

4.1 定时器 + function,this指向window

    setTimeout(function () {
    
    
      console.log(this);
    }, 1000);   // window

5、箭头函数

箭头函数没有自己的this,它的this是继承而来的;默认指向在定义它时所处的对象(宿主对象),此处指父级作用域
注意:箭头函数的this指向无法被call,applay,bind改变,但可以通过改变它上一层对象的this指向来改变它的this指向

5.1 指向上层对象的this

此时的箭头函数的宿主对象是show(),而这个函数的执行需要被obj这个对象调用,所以show() 的this指向是对象obj,所以此时箭头函数的this从show继承而来,也就是对象obj

      let obj = {
    
    
        x: 123,
        show() {
    
    
          setTimeout(() => {
    
    
            console.log(this);
          }, 1000);
        },
      };
      obj.show(); // {x: 123, show: ƒ}
      obj.show.call({
    
     x: 100 }); // 100 show()作为普通函数,它的this指向可以被call改变

5.2 指向window

此时的箭头函数的宿主对象是window,所以此处的this指向的是window

      window.fn3 = () => console.log(this);
      fn3();

输出:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_62918410/article/details/129827403