JavaScript:如何正确找出“this”的值

 · 10 mins read

javaScript初学者很容易被“this”绕晕,函数在不同的地方被调用,其“this”所指代的值都是不同的。但其实只要你掌握了方法,“this”的指代很容易判断。本文就介绍这找出“this”值的方法。

方法一:看函数左侧有没有点号(.)

例子:

cat = {
  name: 'tom',
  sayName: function() {
    console.log(`My name is ${this.name}.`);
  }
}

cat.sayName(); // My name is tom.

在上面例子中,sayName方法左侧有点号,那么点号左侧就是“this”的指向。在这里,“this”指向cat

方法二:call、apply和bind

call、apply和bind是每个函数都有的方法,主要作用是为函数指定执行上下文。在这种情况下,“this”指向call、apply或bind的第一个参数。

cat = {
  name: 'tom'
}

function sayName() {
  console.log(`My name is ${this.name}.`);
}

sayName.call(cat); // My name is tom.

这里的cat对象没有sayName方法,不能直接用cat.sayName()的方法来调用,所以我们用call,为sayName指定执行上下文,所以这里的“this”指向了catapply除了传参方式,其他跟call一样。以下代码展示两者传参差异:

cat = {
  name: 'tom'
}

todos = ['todo1', 'todo2'];

function sayName(todo1, todo2) {
  console.log(`name: ${this.name},todo1: ${todo1},todo2: ${todo2}`);
}

sayName.call(cat, todos[0], todos[1]);

sayName.apply(cat, todos);

call一个一个的传参,apply用数组传参,两者就只有这么一个区别。

还有一个bindbind用法大体跟call一样,只是bind不立即执行函数,而是返回一个函数:

sayNameHandler = sayName.bind(cat);
sayNameHandler();

方法三:“this”是不是在构造函数中

当“this”在构造函数中的时候,它指向用该构造函数生成的实例对象。

function User(name, age) {
  this.name = name;
  this.age = age;
}

user1 = new User('vincent', 17);
console.log(user1); // {name: "vincent", age: 17}

方法四:全局调用

当函数在全局作用域被调用的时候,“this”指向window;严格模式下,“this”指向undefined

function sayName() {
  console.log(this.name);
}

sayName(); // undefined

如果给window.name赋值:

window.name = 'jerry';

function sayName() {
  console.log(this.name);
}

sayName(); // jerry

this.name就指向window.name

在严格模式下:

'use strict';

window.name = 'jerry';

function sayName() {
  console.log(this.name);
}

sayName(); // Uncaught TypeError: Cannot read property 'name' of undefined

“this”指向undefined

以上就是本文的主要内容了,下面留一道思考题给你:

var name= 'tom';
var MyObj = {
  name: 'jerry',
  showName: function(){
    console.log(this.name);
  }
}
setTimeout(MyObj.showName,1000);

这里打印的是什么?