Arrow Function với this

Con trỏ this với hàm không có đối tượng gọi

Ở ví dụ trước chúng ta thường gọi hàm với đối tượng như userJohn.sayHi() hay userPeter.hi(). Còn trong trường hợp khi tạo hàm bình thường không có đối tượng nào gọi nó, context của hàm đó là đối tượng global. Khi sử dụng Javascript ở trình duyệt thì đó là đối tượng window.

1
2
3
4
5
function sayHi() {
  console.log(`this is, ${this}!`); // this is, [Object Window]
  console.log('this is window?', this === window); // true
}
sayHi();

Ngay cả khi gọi hàm mà hàm đó ở trong một object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var user = {
  firstName: "John",
  sayThis() {
    function sayHi() {
      console.log(`this is, ${this}!`); // this is, [Object Window]
      console.log('this is window?', this === window); // true
      console.log('Firstname is ', this.firstName); // undefine
    }
    // gọi hàm không có đối tượng đi kèm thì
    // context lúc này là window
    sayHi(); 
  }
};

user.sayThis();

Trong trường hợp muốn thay đổi context, chúng ta có thể sử dụng hàm bind chúng ta sử dụng như sau:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var user = {
  firstName: "John",
  sayThis() {
    function sayHi() {
      console.log(`this is, ${this}!`); // this is, [Object object]
      console.log('this is window?', this === window); // false
      console.log('Firstname is ', this.firstName); // John
    }
    // gọi hàm không có đối tượng đi kèm
    // nhưng chúng ta bind context muốn sử dụng vào
    sayHi.bind(this)(); 
  }
};

user.sayThis();

Arrow function với con trỏ this

Arrow function (hàm mũi tên) là hàm không có con trỏ this, hay nói cách khác con trỏ this của hàm lúc này là con trỏ this của hàm gọi nó. Hay tương đương với bind(this) như trường hợp ở trên.

Ở ví dụ trên chúng ta thay hàm sayHi thành arrow function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var user = {
  firstName: "John",
  sayThis() {
    var sayHi = () => {
      console.log(`this is, ${this}!`); // this is, [Object object]
      console.log('this is window?', this === window); // false
      console.log('Firstname is ', this.firstName); // John
    }
    // gọi arrow function
    // context lúc này là của context hàm sayThis()
    sayHi(); 
  }
}

user.sayThis(); 

Con trỏ this trong hàm sayHi đã trỏ về context của hàm sayThis(), hay cũng chính là đối tượng user.

Con trỏ this của hàm là tham số của hàm khác

Arrow funtion không có con trỏ this nên các hàm bind(), call(), apply() không có tác dụng.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var user = {
  firstName: "John",
  sayThis(sayHi) {
    sayHi(); 
  }
}
var sayHi = () => {
  console.log(`this is, ${this}!`); // this is, [Object Window]
  console.log('this is window?', this === window); // true
  console.log('Firstname is ', this.firstName); // undefined
};

// gọi arrow function
// context lúc này của hàm sayHi là window mặc dù đã bind
user.sayThis(sayHi.bind(user)); 

Thay vì sử dụng arrow function chúng ta sử dụng function bình thường:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var user = {
  firstName: "John",
  sayThis(sayHi) {
    sayHi();
  }
}
var sayHi = function() {
  console.log(`this is, ${this}!`); // this is, [Object object]
  console.log('this is window?', this === window); // false
  console.log('Firstname is ', this.firstName); // John
};

// gọi function
// tham số hàm sayHi có context lúc này là user
user.sayThis(sayHi.bind(user));