JavaScript

Từ khóa this trong JavaScript

Từ khóa this trong JavaScript
Được viết bởi Minh Hoàng

Series lập trình JavaScript, ngôn ngữ lập trình linh động, thực thi phía client.

Từ khóa this trong JavaScript

Từ khóa this là một trong những từ khóa được sử dụng nhiều trong JavaScript. Trong bài viết này, chúng ta sẽ cùng tìm hiểu mọi thứ về từ khóa này.

1. Từ khóa this là gì?

1.1. Từ khóa this là gì?

this trỏ đến một đối tượng cụ thể. Đối tượng đó phụ thuộc vào cách một hàm có chứa từ khóa this đang được gọi. Tức là từ khóa this được gọi trong hàm sẽ refer đến “chủ sở hữu” (“owner“) của hàm đó.

– Để hiểu hơn về điều này, chúng ta xét 2 ví dụ sau:

Ví dụ 1:
  • Ở ví dụ này, this refer đến “chủ sở hữu” của hàm myFunction() là đối tượng window.
  • this ở đây là đại diện cho đối tượng window.
  • Bởi vì object window đang “sở hữu” (“owns“) hàm myFunction().
[code language=”javascript”]var myVar = 100;

function myFunction() {
var myVar = 200;

document.getElementById("demo1").innerHTML = myVar; // myVar = 200

// this đại diện cho đối tượng [window],
// vì vậy 2 cách gọi sau là tương đương:
document.getElementById("demo2").innerHTML = this.myVar; // myVar = 100
// hoặc:
// document.getElementById("demo2").innerHTML = window.myVar; // myVar = 100
};[/code] Try it »

  • this cũng trỏ đến đối tượng global window ngay cả khi nó được sử dụng bên trong một inner function:
[code language=”javascript”]var myVar = 100;

function myFunction() {
function innerFunction() {
var myVar = 200;

document.getElementById("demo1").innerHTML = myVar; // 200

// Khi được dùng trong một inner function
// this cũng đại diện cho đối tượng [window] document.getElementById("demo2").innerHTML = this.myVar; // 100
// hoặc:
// document.getElementById("demo2").innerHTML = window.myVar; // 100
}

innerFunction();
};[/code] Try it »

Ví dụ 2:
  • Ở ví dụ này, this refer đến “chủ sở hữu” của hàm fullName là đối tượng car.
  • this ở đây là đại diện cho đối tượng car.
  • Bởi vì object car đang “sở hữu” (“owns“) method fullName.
[code language=”javascript”]var car = {
brand : "Toyota",
name : "Prius 2018",
color : "White",
fullName : function() {
return this.brand + " " + this.name; // Toyota Prius 2018
}
};[/code] Try it »

1.2. Trường hợp “this” được dùng bên trong method của một đối tượng

this có thể hoạt động theo cách tương tự như đối với các đối tượng được tạo bằng cách sử dụng object literal, như ví dụ dưới đây this sẽ đại diện cho đối tượng myObj:

[code language=”javascript”]var myVar = 100;

// Tạo đối tượng myObj
var myObj = {
myVar : 300,
myFunction : function(){
var myVar = 200;

document.getElementById("demo1").innerHTML = myVar; // 200
document.getElementById("demo2").innerHTML = this.myVar; // 300
}
};[/code] Try it »

– Ngoài ra, trong JavaScript như đã trình bày ở bài viết Từ khóa new trong JavaScript, bạn có thể tạo một đối tượng của một hàm (function) bằng cách sử dụng từ khóa new. Vì vậy, khi bạn tạo một đối tượng của một hàm bằng cách sử dụng từ khóa new thì this sẽ trỏ đến đối tượng cụ thể đó:

[code language=”javascript”]var myVar = 100;

function myFunction() {
this.myVar = 200;
}

var obj1 = new myFunction();

var obj2 = new myFunction();
obj2.myVar = 300;

alert(obj1.myVar); // 200
alert(obj2.myVar); // 300[/code] Try it »

– Ở ví dụ trên, this trỏ tới obj1 của instance obj1 và trỏ tới obj2 của instance obj2. Trong JavaScript, các thuộc tính có thể được truy cập thông qua đối tượng động (object dynamically) bằng cách sử dụng ký tự dấu chấm. Vì vậy, myVar sẽ là một property của cả hai instances obj1, obj2 và mỗi instance này sẽ có một bản sao riêng biệt (separate copy) của myVar.

– Chúng ta cùng xét thêm một ví dụ nữa:

[code language=”javascript”]var myVar = 100;

function myFunction() {
this.myVar = 200;
this.display = function(){
var myVar = 300;

alert("myVar = " + myVar); // 300
alert("this.myVar = " + this.myVar); // 200
};
}

var obj = new myFunction();
obj.display();[/code] Try it »

– Ở ví dụ trên, obj sẽ có hai thuộc tính myVar và display (display là một biểu thức hàm / function expression). Vì vậy, this bên trong method display() sẽ trỏ tới obj khi gọi obj.display().

2. Default Binding

2. Default Binding

– Khi được sử dụng một mình, this refer đến đối tượng Global. Với trình duyệt (browser) thì đối tượng Global chính là [object Window]:

Ví dụ:
[code language=”javascript”]var x = this;[/code] Try it »

– Từ khóa this của một hàm hoạt động hơi khác một chút so với các ngôn ngữ khác (như đã trình bày bằng các ví dụ ở mục 1. phía trên). Ngoài ra, nó cũng có sự khác biệt giữa chế độ nghiêm ngặt (strict mode) và chế độ không nghiêm ngặt (non-strict mode):

Với chế độ không nghiêm ngặt (non-strict mode):

Khi được sử dụng trong một hàm, this refers đến Global object (tức là đối tượng window):

Ví dụ:
[code language=”javascript”]function myFunction() {
return this;
}[/code] Try it »

Với chế độ nghiêm ngặt (strict mode):

– Trong strict mode, this sẽ là undefined, vì strict mode không cho phép default binding:

Ví dụ:
[code language=”javascript”]"use strict";
function myFunction() {
return this;
}[/code] Try it »
3. Object Method Binding

3. Object Method Binding

Trong các ví dụ bên dưới, this là đối tượng car (vì đối tượng car là “owner” của hàm):

Ví dụ:
[code language=”javascript”]var car = {
brand : "Toyota",
name : "Prius 2018",
color : "White",
myFunction : function() {
return this; // [object Object] }
};[/code] Try it »

Ví dụ:
[code language=”javascript”]var car = {
brand : "Toyota",
name : "Prius 2018",
color : "White",
myFunction : function() {
return this.brand + " " + this.name; // Toyota Prius 2018
}
};[/code] Try it »

– Nói cách khác: this.brand có nghĩa là thuộc tính (property) brand của this (car) object.

4. Explicit Function Binding

4. Explicit Function Binding

– Trong JavaScript, một hàm có thể được gọi bằng cách sử dụng toán tử (), như phương thức call()apply() ở ví dụ sau đây:

Ví dụ:
[code language=”javascript”]function myFunction() {
alert(‘Hi! Have a nice day!’);
}

myFunction(); // Sử dụng toán tử ()
myFunction.call(); // Sử dụng call()
myFunction.apply(); // Sử dụng apply()[/code] Try it »

– Ở ví dụ trên, myFunction(), myFunction.call()myFunction.apply() thực hiện một hàm theo cùng một cách và cùng cho kết quả giống nhau.

– Mục đích chính của call()apply() là set context của this bên trong một hàm bất kể hàm đó đang được gọi trong phạm vi toàn cục (global scope) hay là phương thức của đối tượng (object’s method).

– Bạn có thể truyền một đối tượng như là một tham số của call()apply(). Cả hai có thể được sử dụng để gọi một phương thức đối tượng (object method) với tham số (argument) là một đối tượng khác.

– Ở ví dụ sau đây, khi gọi phương thức car1.fullName, sẽ truyền đối số là object car2:

Ví dụ:
[code language=”javascript”]var car1 = {
fullName: function() {
return this.brand + " " + this.name;
}
}
var car2 = {
brand:"Toyota",
name:"Prius 2018",
}
var x = car1.fullName.call(car2); // return Toyota Prius 2018[/code] Try it »

– Hoặc có một ví dụ khác:

Ví dụ:
[code language=”javascript”]var myVar = 100;

function myFunction() {
alert(this.myVar);
}

var obj1 = { myVar : 200 , myFunction: myFunction };
var obj2 = { myVar : 300 , myFunction: myFunction };

myFunction(); // 100

// truyền tham số là object obj1
myFunction.call(obj1); // 200

// truyền tham số là object obj2
myFunction.apply(obj2); // 300

obj1.myFunction.call(window); // 100[/code] Try it »

Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi!

Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp bạn đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[...]

Translate »