11/08/2018, 20:08

Hướng dẫn tạo class trong Javascript

Bài này mình sẽ tổng hợp các cách viết class trong Javascript. Để viết class chúng ta dùng function, còn để tạo singleton thì có thể dùng Object hoặc Anonymous Function. Tạo class bằng function Định nghĩ một class mới bằng từ khóa function và sử dụng các biến cho instance bằng từ khóa this ...

Bài này mình sẽ tổng hợp các cách viết class trong Javascript. Để viết class chúng ta dùng function, còn để tạo singleton thì có thể dùng Object hoặc Anonymous Function.

Tạo class bằng function

Định nghĩ một class mới bằng từ khóa function và sử dụng các biến cho instance bằng từ khóa this

function Person(name,birthYear) {
  this.name = name;
  this.birthYear = birthYear;
  this.getAge = function() {
    return new Date().getFullYear() - birthYear;
  }
}
var p = new Person("TH",1991);
p.getAge(); // 24

Ở đây hàm getAge được định nghĩa trực tiếp. Cách này có một nhược điểm là mỗi lần một instance mới được tạo ra thì hàm đó lại được định nghĩa lại. Cách làm tốt hơn là định nghĩa sau thông qua Prototype

function Person(name,birthYear) {
  this.name = name;
  this.birthYear = birthYear;
}
Person.prototype.getAge = function() {
  return new Date().getFullYear() - this.birthYear;
}
var p = new Person("TH",1991);
p.getAge(); // 24

Too easy

Tạo Singleton bằng Object hoặc Anonymous function

Giờ đến Singleton thì sao nhỉ :) Cách đầu tiên là tạo object giống như cách viết Jquery plugins. Mình sẽ tạo thẳng một object như sau

var person = {
  name: "TH",
  birthYear: 1991,
  getAge: function() {
    return new Date().getFullYear() - this.birthYear;
  }
}

Hoặc cũng có thể tạo được thông qua một anonymous function, giống cách 1 nhưng bây giờ là gán new function cho biến person.

var person = new function() {
  this.name = "TH";
  this.birthYear = 1991;
  this.getAge = function() {
    return new Date().getFullYear() - this.birthYear;
  }
}

Các bạn chú ý là Singleton thì chỉ tạo được một object không giống như class tạo được nhiều instance khác nhau nhé. Tạo class bằng Javascript có một điểm nguy hiểm cần chú ý.
Quay lại cách làm đầu tiên

function Person(name,birthYear) {
  this.name = name;
  this.birthYear = birthYear;
  this.getAge = function() {
    return new Date().getFullYear() - birthYear;
  }
}

Lúc này khi tạo instance mới

var err = Person("Grawwwww",2000);

Bạn có để ý thấy thiếu gì ko, thiếu từ khóa new đó!

console.log(err); // undefined ???
console.log(window.name); // Grawwwww ???

Global Leak

Hiện tượng này gọi là Global Leak. Để tránh Global Leak thì có best practise được suggest trên Stack OverFlow: http://stackoverflow.com/questions/1580863/javascript-how-to-create-a-new-instance-of-a-class-without-using-the-new-keywor/10836513#10836513

function Person(name, birthYear) {
  // Check !!
  if (!(this instanceof Person)) {
    return new Person(name, birthYear);
  }
  this.name = name;
  this.birthYear = birthYear;
}
var err = Person("Grawwwww",2000);
console.log(err); // Person {name: "Grawwwww", birthYear: 2000}

Class trong ES6

EcmaScript 6 ra đời đã giải quyết vấn đề dứt điểm bằng một cấu trúc thuần OOP hơn. Giờ đây chúng ta có thể sử dụng trực tiếp từ khóa class để tạo một class mới. Khi khởi tạo nếu thiếu từ khóa new thì ngay lập tức sẽ bị lỗi.

class Person {
  constructor(name,birthYear) {
    this.name = name;
    this.birthYear = birthYear;
  }
  getAge() {
    return new Date().getFullYear() - this.birthYear;
  }
}

var nt = new Person('Ngoc Trinh',1989);
nt.getAge(); // 26
var pt = Person('Phuong Trinh',1995); // Uncaught TypeError: Cannot call a class as a function(…)

ES6 còn nhiều tính năng rất hay, mình sẽ viết tiếp trong phần sau nhé!

0