JS中的this指向问题

33 阅读2分钟

JS中this问题

先看一段代码

在这段代码中,定义一个普通函数,并在函数中打印this

然后以不同的方式调用,打印出不同的结果

  function fn() {
    console.log(this);
  }
// 直接调用
  fn();

  let obj = {
    name: 'zzk'
  };
// call调用
  fn.call(obj)

  let obj2 = {
    name: 'sss',
    func: fn
  }
  obj2.func()

打印结果

image-20231212191703493.png

得出的结论时this只有在函数调用时才能决定this是谁

this的绑定规则分为

  • 默认绑定
  • 隐式绑定
  • 显示绑定
  • new绑定

1.默认绑定

独立函数调用既默认绑定,没有绑定到某个对象上的调用函数

// --------------- 独立的函数调用
function fn() {
    console.log(this);
}
// 独立的函数调用
// 函数内部的this,在浏览器中表示window
fn(); // window

打印结果:

image-20231212192245497.png

2.隐式绑定

通过某一个对象进行调用

function fn() {
    console.log(this);
}
var obj = {
    name: "zzk",
    fn: fn,
}

obj.fn(); // 打印出对象obj

打印结果:

image-20231212191743761.png 隐式绑定回把obj对象绑定到this上


// --------------- 隐式绑定
var obj = {
    name: "wc",
    fn: function() {
        console.log(this);
    }
}
var obj2 = {
    name: "xq",
    gn: obj.fn
}
// fn中this是谁,看.前面是谁
obj2.gn(); // obj2

image-20231212192936528.png

3.显示绑定

通过call,apply,bind可以改变this的指向

function fn() {
    console.log(this);
}
let obj = {
    name: "zzk",
}

fn.call(obj)	// obj

fn.apply(obj)	// obj

let newFn = fn.bind(obj)
newFn();		// obj

image-20231212192936528.png 如果call,bind后面跟的是基本数据类型

function fn() {
    console.log("fn...");
    console.log(this);
}
fn.call("hello"); // 会把"hello"包装成一个新的对象
fn.call(undefined); // 参数是und this指定window
fn.call(null); // 参数是null this指定window

4.new绑定

使用new关键字,创建一个新的对象,会执行如下步骤

  • 创建一个新对象
  • 这个空对象prototype会指向构造函数的原型,
  • 新对象会绑定到函数调用的this上
  • 如果函数没有返回其他对象,则表达式会返回这个新对象

5.箭头函数绑定

箭头函数的this会指向上层作用域


console.log(this); // 最外层的this是window

var fn = () => {
    // 箭头函数中的this都需要向外找一级
    console.log(this);
}
fn(); // window

var obj = {
    name: "wc"
}
fn.call(obj); // window

示例中始终指向window