Skip to content

this指向

this指向当前函数的调用者,如果当前函数没有调用者,那么this指向全局对象。

普通函数

谁调用这个函数,this就指向谁

需要注意的是严格模式下,普通函数的指向是undefined

js
function foo() {
  console.log(this);
}

foo(); // window

setTimeout(function() {
  console.log(this);
})
// window 其实本质上是window.setTimeout
js
var obj = {
  foo: function() {
    console.log(this);
  }
};

obj.foo(); // obj

箭头函数

箭头函数没有自己的this,它继承自最近作用域的this。

js
var obj = {
  foo: function() {
    console.log(this);
  },
  bar: () => {
    console.log(this);
  }
};

obj.foo(); // obj
obj.bar(); // window

构造函数

构造函数的this指向实例对象

js
function Foo() {
  console.log(this);
}

new Foo(); // Foo {}

改变this指向

  1. call
  2. apply
  3. bind

使用

js
function foo() {
  console.log(this);
}

foo.call({ name: 'foo' }); // { name: 'foo' }

foo.apply({ name: 'foo' }); // { name: 'foo' }

foo.bind({ name: 'foo' })(); // { name: 'foo' }

1、call

call的参数,第一个参数是this指向的对象,后面的参数是函数的参数 函数立即执行

js
function foo() {
  console.log(this);
}
foo.call({ name: 'foo' }); // { name: 'foo' }

call的参数,第一个参数是this指向的对象,后面的参数是函数的参数

js
function foo(a, b) {
  console.log(this, a, b);
}
foo.call({ name: 'foo' }, 1, 2); 
// { name: 'foo' } 1 2

2、apply

apply的参数,第一个参数是this指向的对象,第二个参数是函数的参数数组

函数立即执行

js
function foo() {
  console.log(this);
}
foo.apply({ name: 'foo' }); // { name: 'foo' }

使用场景:数组最大值

js
const arr = [1, 2, 3, 4, 5];
console.log(Math.max.apply(null, arr)); // 5

3、bind

bind返回一个函数,不会立即执行

js
function foo() {
  console.log(this);
}
foo.bind({ name: 'foo' })(); // { name: 'foo' }

4、总结call apply bind

相同点

  1. 都是用来改变this指向的
  2. 都可以用来调用函数

不同点

  1. call和apply会立即执行函数
  2. bind不会立即执行函数,会返回一个函数

call和apply的区别

  1. call的参数是逐个传入的call({}, 1, 2, 3)
  2. apply的参数是数组 apply({}, [1, 2, 3])

应用场景

  1. call调用函数并传递参数
  2. apply经常用来处理数组
  3. bind经常用来改变this指向并且不立即执行函数,例如:事件处理函数、定时器函数

箭头函数

  • 箭头函数没有this,箭头函数的this指向的是定义时的this,而不是执行时的this
js
function foo() {
  console.log(this);
  return () => {
    console.log(this);  // 定义时的this 指向的是foo函数的this   
  };
}
foo.call({ name: 'foo' })(); // { name: 'foo' } { name: 'foo' }
  • 箭头函数没有arguments
js
function foo() {
  console.log(arguments);
  return () => {
    console.log(arguments);  // 报错
  };
}
foo.call({ name: 'foo' })(); // { name: 'foo' } { name: 'foo' }

Released under the MIT License.