Phương Thức Trong JavaScript: Xử Lý Biến this Một Cách Chính Xác

Trong JavaScript, một hàm được gán vào đối tượng được gọi là phương thức. Phương thức này có thể truy cập và thay đổi thuộc tính của đối tượng thông qua từ khóa this.

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992,
  calculateAge: function() {
    const currentYear = new Date().getFullYear();
    return currentYear - this.yearOfBirth;
  }
};

user.calculateAge(); // Kết quả: 32 (tùy năm hiện tại)

Khi gọi phương thức qua đối tượng (user.calculateAge()), this trỏ đến user. Tuy nhiên, nếu gọi trực tiếp hàm:

function calculate() {
  return new Date().getFullYear() - this.yearOfBirth;
}

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992,
  getAge: calculate
};

user.getAge(); // 32
calculate(); // NaN (vì this trỏ đến window)

Trong chế độ nghiêm ngặt ('use strict'), this sẽ là undefined khi gọi hàm trực tiếp, gây ra lỗi:

'use strict';

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992,
  calculate: function() {
    return new Date().getFullYear() - this.yearOfBirth;
  }
};

const getAge = user.calculate;
getAge(); // Lỗi: Cannot read property 'yearOfBirth' of undefined

Trong trường hợp phương thức lồng nhau, this bị mất:

'use strict';

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992,
  getAge: function() {
    const calculate = function() {
      return new Date().getFullYear() - this.yearOfBirth; // Lỗi
    };
    return calculate();
  }
};

user.getAge(); // Lỗi

Giải pháp: Lưu giá trị this vào biến self ngay khi bắt đầu phương thức:

'use strict';

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992,
  getAge: function() {
    const self = this;
    const calculate = function() {
      return new Date().getFullYear() - self.yearOfBirth;
    };
    return calculate();
  }
};

user.getAge(); // 32

Để kiểm soát this, sử dụng phương thức apply() hoặc call():

function calculate() {
  return new Date().getFullYear() - this.yearOfBirth;
}

const user = {
  username: 'JohnDoe',
  yearOfBirth: 1992
};

calculate.apply(user, []); // 32
calculate.call(user); // 32

Phương thức apply() nhận tham số dưới dạng mảng, trong khi call() nhận từng tham số riêng lẻ:

Math.max.apply(null, [10, 5, 20]); // 20
Math.max.call(null, 10, 5, 20); // 20

Ứng dụng của apply() để mở rộng hành vi hàm:

'use strict';

let callCount = 0;
const originalParse = parseFloat;
window.parseFloat = function() {
  callCount++;
  return originalParse.apply(null, arguments);
};

parseFloat('15.5'); // 15.5
parseFloat('20.3'); // 20.3
console.log(callCount); // 2

Thẻ: javascript-methods this-keyword apply call strict-mode

Đăng vào ngày 18 tháng 5 lúc 08:01