JavaScript中this的指向问题及面试题你掌握了吗?

this 作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的。这里先做一个结论,重要事情说三遍:

this的指向是由上下文环境动态决定的

this的指向是由上下文环境动态决定的

this的指向是由上下文环境动态决定的

我自己是一名从事了多年开发的web前端老程序员,前段时间我花了一个月整理了一份最适合学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以添加下面的QQ群,即可免费获取。

在这里插入图片描述

this指向实例场景
关于this的指向的不确定性,主要体现在如下几个应用场景中:

全局环境
普通函数调用
由call/apply/bind函数调用
对象属性方法调用
构造函数调用
箭头函数
全局环境
在全局环境中无论是否是严格模式,this 均指向全局对象,例如浏览器端的 window

// 在浏览器中, window 对象同时也是全局对象:

```javascript
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"

普通函数调用
当普通的函数,直接调用的时候,一般来说分两种情况:

严格模式绑定到 undefined
非严格模式绑定到全局对象 window

```javascript
function foo(){
  console.log(this);  
}
function bar(){
  "use strict"; 
  console.log(this);
}
foo() // window
bar() // undefined

call/apply/bind函数调用
call/apply 这两个函数对象到方法能立即执行某个函数,并且讲函数中的this绑定到你提供到对象上去

bind 方法永久的绑定函数中的this到指定对象上,并返回一个新函数,将来这个函数无论怎么调用都可以

function foo(){
    
    
  console.log(this);  
}
function bar(){
    
    
  console.log(this);
}
foo.call({
    
    name:'小米'}); // {name: "小米"}

const bar1 = bar.bind({
    
    num:123})
bar1() // {num: 123}

对象属性方法调用
作为对象属性方法调用,都指向前面调用函数都那个对象。当然有的时候会出现各种变种或者干扰的面试题

const student = {
    
    
  name: "tom",

  fn: function () {
    
    
    return this;
  },
};
console.log(student.fn() === student);

构造函数调用或者类上下文
构造函数作为JavaScript创建对象的那只大母鸡(实际上类是构造函数的语法糖),通常程序界有个段子叫做new 一个对象,谁还敢说程序员(媛)没有对象的,这种方式调用this指向的是你new出来的那个对象实例本身:

function Person(name){
    
    
  console.log(this);
  this.name = name
}

const p = new Person('tom')
console.log(p);

箭头函数中的this
箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

var obj = {
    
    
  name: "tom",
  foo() {
    
    
    setTimeout(() => {
    
    
      console.log(this);
    }, 1000);
  },
};

obj.foo() // obj

面试题
常见面试题有: 1、手写bind函数

Function.prototype.mybind = function (ctx, ...args) {
    
    
  const fn = this;
  return function () {
    
    
    fn.apply(ctx, args);
  };
};

function foo(x, y) {
    
    
  console.log(this, x, y);
}

const foo1 = foo.mybind({
    
     name: "zhangsan" }, 10, 20);
foo1();

2、new 操作符调用构造函数,具体做了什么?

创建一个新的对象;
将构造函数的 this 指向这个新对象;
为这个对象添加属性、方法等;
最终返回新对象。

猜你喜欢

转载自blog.csdn.net/ZYDX18984003806/article/details/113942204