What is this

Bài viết đề cập đến 1 từ khóa thông dụng trong javascript

this

4 pattern của this

  • gọi phương thức (method)
  • gọi hàm số (function)
  • gọi constructor
  • gọi apply, call

Gọi phương thức (method)

Đây là pattern rất đơn giản và dễ hiểu. this đại diện cho object và có thể dùng để gọi method.

var sampleObject = {
  value: 1,
  show: function() {
    console.log(this.value);
  }
}
myObject.show(); // 1

Trong trường hợp này this đại diện cho sampleObject và chúng ta có thể dùng nó để gọi method value. Kết quả là giá trị được log ra là 1.

Gọi hàm số (function)

Trong javascript tồn tại khái niệm method và function. Nếu nhìn qua bề ngoài thì cách gọi method và function chỉ khác nhau chút ít.

sampleObject.show(); // gọi method
show(); // gọi function

Khi gọi method thì chúng ta cần phải có đối tượng sử dụng method đó và this đại diện cho đối tượng đó vậy khi gọi function thì this đại diện cho cái gì.

function show() {
  console.log(this);
  this.value = 2;
}
show(); // Window{...}
value; // 2

Trong trường hợp này this sẽ đại diện cho global object mà cụ thể là Window object. Điều đó có nghĩa là value là 1 biến global .

Nghịch thử 1 chút với 2 kiểu this ở trên

var sampleObject = {
  value: 1,
  show: function() {
    console.log(this.value);

    function show() {
      console.log(this.value);
    }
    show();
  }
}

Kết quả được in ra ở log là gì ?

Nhin qua thì 2 lệnh log trông có vẻ giống giống nhau nhưng kết quả thì lại khác. 2 lệnh log là đại diện cho 2 pattern sử dụng this ở trên Lệnh đầu tiên là pattern gọi method. this đại diện cho sampleObject và this.value trả về 1. Trong lệnh thứ hai Rắc rối hơn 1 chút, câu lệnh triệu hồi this nằm trong 1 function mà function này lại nằm trong lời gọi của 1 method. Vậy phải xử lí theo case nào đây :-? Kết quả là this thứ 2 này rơi vào case 2, là global object do đó this.value trả về undefine myObject.show();

Vậy nếu muốn cả 2 this đều trả về sampleObject thì sao. Giải pháp đơn giản là thêm 1 biền self nữa

var sampleObject {
  value: 1,
  show: function() {
    var self = this;
    console.log(self.value); // 1
    function show() {
      console.log(self.value); // 1
    }
    show();
  }
};

myObject.show();

Cách làm này khá thông dụng với việc sử dụng thêm các biến kiểu như that, self, _this và gán cho nó giá trị của 1 this khác

Gọi constructor

Hãy xem xét ví dụ dưới đây

function SampleObject(value) {
  this.value = value;
  this.increment = function() {
    this.value++;
  };
}

var sampleObject = new SampleObject(0);
console.log(sampleObject.value); // 0

myObject.increment();
console.log(sampleObject.value); // 1

Trong ví dụ này, this đại diện cho instance được tạo ra từ new SampleObject(0).

Gọi apply, call

apply,call呼び出しパターン
var sampleObject = {
  value: 1,
  show: function() {
    console.log(this.value);
  }
};
var yourObject = {
  value: 3
};

sampleObject.show(); // 1

sampleObject.show.apply(yourObject); // 3
myObsampleObjectject.show.call(yourObject); // 3

Khi sử dụng callapply thì this đại diện cho đối số dầu tiên của lời gọi (trong ví dụ này là yourObject)

Cách sử dụng callthis là tương đối giống nhau chỉ có sự khác biệt trong lời gọi với các đối số từ thứ 2 trở đi

var myObject = {
  add: function(value1, value2) {
    console.log(this.value + value1 + value2);
  }
};
var yourObject = {
  value: 3
};

myObject.add.apply(yourObject, [2, 10]); // 15
myObject.add.call(yourObject, 2, 10); // 15

Tuy nhiên cả 2 đều giống nhau ở điểm đối số đầu tiên chính là đối tượng mà this đại diện cho

Tổng kết

Có 4 pattern cơ bản khi sử dụng this

  • gọi phương thức (method)
  • gọi hàm số (function)
  • gọi constructor
  • gọi apply, call

Nắm rõ 4 pattern cơ bản khi sử dụng this nói trên sẽ giúp bạn hiểu rõ hơn và vận dụng tốt hơn từ khóa phổ biến trong javascript này 😄