JS中this的问题

80 阅读2分钟

❗ 函数内部中的 this 指向谁,不是在函数定义时决定的而是在函数第一次调用并执行的时候决定

1. call 方法

语法:函数名.call(调用者, 参数1, …)
作用:函数被借用时,会立即执行,并且函数体内的this会指向借用者或调用者

function fn(name, age) {
    this.name = name;
    this.age = age;
}
const obj = {}
// 经过call,this指向obj,obj开始有name、age属性
fn.call(obj, '李四', 100)
// 以下this均指向window,name:undefined,age:undefined
fn.call()
fn.call(null)
fn.call(undefined)

结果:普通函数的this指向window,利用call方法将this指向了obj

2. apply方法

语法:函数名.apply(调用者, [参数, …])
作用:函数被借用时,会立即执行,并且函数体内的this会指向借用者或调用者

function fn(name, age) {
    this.name = name;
    this.age = age;
}
const obj = {}
// 经过apply,this指向obj,obj开始有name、age属性
fn.apply(obj, ['李四', 100])
// 以下this均指向window,name:undefined,age:undefined
fn.apply()
fn.apply(null)
fn.apply(undefined)

结果:普通函数的this指向window,利用apply方法将this指向了obj

3. bind方法

语法:函数名.bind(调用者, 参数, …)
作用:函数被借用时,不会立即执行,而是返回一个新的函数。需要自己手动调用新的函数来改变this指向

function fun() {
    console.log(this);  // 原来的函数this指向的是 Window
}
fun();
 
function fun(a, b) {
    console.log(this); // this指向了输入的 字符串bind
    console.log(a + b);
}
//使用bind() 方法改变this指向,此时第一个参数是 字符串bind,那么就会指向字符串bind
let c = fun.bind('bind', 2, 3);
c(); // 返回新的方法,需要重新调用
// 也可以使用下面两种方法进行调用
// fun.bind('bind', 2, 3)();
// fun.bind('bind')(2, 3);

结果:普通函数的this指向window,利用bind方法将this指向了obj

💤总结: 相同点: 三者都可以把一个函数应用到其他对象身上,注意不是自身对象 不同点:

  • ○ call,apply是直接执行函数调用。bind是绑定,执行需要再次调用。
  • ○ call,bind接收逗号分隔的无限个参数列表;apply接收数组作为参数。

new

还有一个改变this指向的问题是new关键字。this指向实例对象。

优先级

  • new 关键字最高
  • 显示绑定其次(call、bind、apply)
  • 隐士绑定(第三)可能存在隐士丢失的问题obj.foo()
  • 默认绑定最低(window)