Biết rồi, khổ lắm nói mãi class es6. Nhưng sự thật vẫn chưa biết.

Nội dung bài viết

Video học lập trình mỗi ngày

ES6 (ECMAScript2015) là một bản nâng cấp lớn cho JavaScript. Trong bài viết này, chúng ta sẽ tìm hiểu về class es6 để hiểu sâu hơn những cụm từ hay những khái niệm như class, object, static properties, constructor, inheritance, super và extends trong JavaScript. 

Nếu bạn là một developer javascript thì bạn hẳn phải biết rằng javascript tuân theo sự kế thưà prototypal, nhưng đôi khi nó hơi lộn xộn tuỳ theo từng devjs. Tuy nhiên sự ra đời với class es6 thì cú pháp sẽ đơn giản và trực quan hơn nhiều. 

Nhưng trước khi bạn đọc bài này thì mình nghĩ các bạn nên thử xem qua cách khác nhau giữa es5 và es6 khi cùng triển khai một cú pháp như class.


 1 - Object Oriented Programming (OOP) là gì? 


Mình nói ngắn gọn thôi chứ theo định nghĩa thì phải có một bài viết rõ về ông này. OOP dạng như là mô tả một cách để viết chương trình. Cách này tập trung vào dữ liệu: được lưu trữ dưới dạng các thuộc tính của đối tượng và các hành động. Tóm lại OOP không có gì ngoài code xung quanh đối tượng đó. Vậy thôi =]]. Ai phỏng vấn mà hỏi, bạn cứ trả lời xung quang như vậy. Miễn là hiểu được. Và quan trọng hơn bạn nên phân biệt giữa __proto__ và prototype trong OOP.


Tài liệu liên quan: Prototype là gì? Lập trình hướng đối tượng OOP trong javascript


2 - Nói về Class và Object


Đương nhiên về điều này thì ai cũng biết rồi nhưng để minh nói qua một chút nữa cho bạn nào đang mơ hồ thì có thể vững tin hơn. Object là một thứ có thể nhìn thấy hoặc chạm vào và trong javascript, các devjs luôn luôn thể hiện nhiều với các object. Class nó đương nhiên không phải là môt object, nó giống như một bản thiết kế để tạo ra các đối tượng, giúp các object đó đi với các thuộc tính và khả năng của đối tượng đó.


3 - OOP trước khi đi vào es6


Thời nguyên thuỷ, or thời tần thuỷ hoàng có lẽ cũng đã chứng kiến nhiều đối tượng được viết như thế này: 

Thời tần thuỷ hoàng

const user1 = {name: 'messi', age: 31, email: 'messi@gmail.com'}
const user2 = {name: 'ronaldo', age: 32, email: 'ronaldo@gmail.com'}
const user3 = {name: 'nani', age: 31, email: 'nani@gmail.com'}

Chính vì lẽ đó cho nên mới có những ngày tháng tươi đẹp, và có lẽ tốt hơn với một template cho user, mà chúng ta chỉ nhập dữ liệu khi chúng ta muốn tạo object cho user mới. 

Thời khai sáng.

function User(name, age, emmail){
this.name = name;
  this.age = age;
  this.email = email;
}

const user1 = new User('messi', 31, 'messi@gmail.com')
const user2 = new User('ronaldo', 32, 'ronaldo@gmail.com')
const user3 = new User('nani', 31, 'nani@gmail.com')

Các bạn có thể cũng biết cách viết kiểu này chính là hướng đối tượng OOP. Nhưng với class es6 sẽ giúp chúng ta làm tốt hơn nữa để làm điều đó.


4 - OOP với ES6


Ông nào or bạn nào bước qua es6 này mà làm PHP hay JAVA thì có lẽ nhìn quen quen và thân thuộc hơn. 

Giờ đi vào cú pháp cho nhanh

class User {
constructor(name, age, emmail){
  this.name = name;
    this.age = age;
    this.email = email;
  }
}

const user1 = new User('messi', 31, 'messi@gmail.com')
const user2 = new User('ronaldo', 32, 'ronaldo@gmail.com')
const user3 = new User('nani', 31, 'nani@gmail.com')

Về cơ bản thì class sẽ tạo ra một template để chúng ta có thể sử dụng những object sau này. Hàm lớp về cơ bản tạo ra một khuôn mẫu mà chúng ta có thể sử dụng để tạo các đối tượng sau này. Method constructor () là một method nó sẽ tự động được gọi khi đối tượng được khởi tạo. 

Có ai tinh mắt or tinh ý thì đều nhìn nhận rằng điều này về cơ bản giống như ví dụ trước đó là thời khai sáng. Rất đúng và chi lý nhưng... từ từ đừng vội hay còn phía sau. 

Method được khai báo như thế nào? Tiếp tục theo dõi nhé mấy bạn

class User {
constructor(name, age, email){
  this.name = name;
    this.age = age;
    this.email = email;
  }
  increaseAge(){
   this.age += 1; //tăng thêm tuổi  
  }
}

const user1 = new User('messi', 31, 'messi@gmail.com')
console.log(user1); //User {name: "messi", age: 31, email: "messi@gmail.com"}
user1.increaseAge()
console.log(user1); // User {name: "messi", age: 32, email: "messi@gmail.com"}

Okay, ngoài ra thì class ES6 chứa các static method. 

Nên nhớ static method không phải là một object, mà chỉ qua là một function được liên kết với class. Và method này không thể gọi từ một instance class.

 Thêm ví dụ nữa về static và cách gọi

class User {
constructor(name, age, email){
  this.name = name;
    this.age = age;
    this.email = email;
  }
  increaseAge(){
  this.age += 1; //tăng thêm tuổi
  }
  static staticMethod(){
  return 'Im a static method '
  }
}

const user1 = new User('messi', 31, 'messi@gmail.com')

console.log(User.staticMethod());//Im a static method 

console.log(user1.staticMethod())//Uncaught TypeError: user1.staticMethod is not a function


5 - Getter và Setter.


Chúng ta chuẩn bị đi qua một ví dụ nữa về tính đóng gói (encapsulation) một trong những phần quan trọng của OOP. và phần quan trọng của việc đóng gói là dữ liệu(object properties) không nên cho phép truy cập or sửa đổi trực tiếp từ bên ngoài object. Để set or get thì ta sẽ sử dụng các phương thức mà chúng ta sẽ định nghĩa trong class. Hãy nhìn ví dụ tiếp theo.

class Meetup {
    constructor(name) {
        this._name = name;
    }
    get name() {
        // Validation can happen on data
        return this._name;
    }
    set name(val) {
        // Validation can happen on data
        this._name = val;
    }
}
let meetup = new Meetup('JS');
console.log("meetup Name: " + meetup.name); // meetup Name: JS
meetup.name = 'Angular';
console.log("meetup Name: " + meetup.name); // meetup Name: Angular

Để mình giải thích thêm một chút nữa với get và set. 

- Với getter và setter, sẽ có nhiều quyền kiểm soát hơn đối với các object properties sau khi khởi tạo với constructor. 

- Các devjs có thể validation dữ liệu trong phương thức get và set trước khi setting or getting giá trị. 

- Chúng ta có thể thấy trong ví dụ trên có property name là _name nhưng chúng ta đang sử dụng nó làm metup.name và nó hoạt động tốt vì các method getter và setter. 

ok tiếp nào. hay hơn rồi.


6 - Inheritance trong ES6


Tiếp tục đi vào ví dụ, à tôi nói về cách học một chút nha. Học gì thì gì nên đọc qua các ví dụ thật kỹ, có khi nhìn ví dụ hiểu lý thuyết chứ chưa chắc hiểu lý thuyết mà giỏi ví dụ đâu nha. ví dụ:

class Meetup {
}
class techMeet extends Meetup {
}
class sportMeet extends Meetup {
}
let js = new techMeet();
console.log(js instanceof techMeet);  // true
console.log(js instanceof Meetup);    // true
console.log(js instanceof Object);    // true

Trên ví dụ kia tôi tạo thêm 2 class là techMeet và sportMeet bằng cách sử dụng extends. Chúng ta có thể thấy rằng đối tượng js là ví dụ của lớp techMeet và Meetup cả vì class techMeet mở rộng của class Meetup. 

Đến đây có một khái niệm nè, Câu hỏi sự khác biệt giữa typeof và instanceof là gì? Tìm hiểu luôn nha mấy cha nội. Thêm ví dụ nữa nè: Học cho chắc luôn

class Meetup {
    constructor() {
        console.log("inside Meetup constructor");
    }
}
class techMeet extends Meetup {
    constructor() {
        super();
        console.log("inside techMeet constructor");
    }
}
let js = new techMeet();
// inside Meetup constructor
// inside techMeet constructor

Giải thích về đoạn mã trên :

Bên trong hàm constructor của techMeet lớp con, chúng ta phải gọi phương thức super () để gọi hàm parent constructor trước nếu không JavaScript sẽ xuất hiện lỗi.

 Phương thức super () không có là gì ngoài function constructor của class Parent. 

lệnh gọi super () phải có trong hàm tạo của lớp dẫn xuất cho dù sự hiện diện rõ ràng của hàm tạo cha có tồn tại hay không. 

7 - Kết luận

Vậy là xong rồi, nhập tâm quá nên hơi dài một chút. Tóm lại bài viết này giúp các bạn những gì? 

  • giới thiệu ngắn gọn về OOP trong JavaScript với cú pháp lớp ES6 
  • typeof và instanceof khác nhau cái gì? 
  • super()? 
  • OOP? 

Đây là một giới thiệu ngắn gọn về OOP trong JavaScript với cú pháp lớp ES6. OOP là một chủ đề lớn, nhưng hy vọng bài viết này đã cho bạn thấy những lợi ích của việc sử dụng nó khi viết mã. Cú pháp lớp ES6 cung cấp cho chúng ta một cách dễ dàng hơn để làm việc với các đối tượng và kế thừa và làm cho việc viết JavaScript hướng đối tượng trở nên dễ dàng hơn.

 Các thay đổi cú pháp trong ES6 và các tính năng mới đang giúp viết mã tốt hơn, sạch hơn và ít mã hơn để đạt được các khái niệm hướng đối tượng trong JavaScript. Xin chào và hẹn gặp lại. 


Bài viết có tham khảo từ nhiều nguồn: 

https://codeburst.io/javascript-object-oriented-programming-using-es6-3cd2ac7fbbd8

https://dev.to/shoupn/javascript-classes-from-es6-and-beyond-3hb5

https://medium.com/beginners-guide-to-mobile-web-development/javascript-introduction-to-es6-classes-ecb2db9fe985

https://medium.com/@luke_smaki/javascript-es6-classes-8a34b0a6720a

Có thể bạn đã bị missing