Constructor.js , class.js và constructor in class javascript

Xin chào tất cả các bạn devjs. Đây là bài chia sẻ về những tình huống thực tế trong phỏng vấn mà bạn thường xuyên gặp. Và trong bài biết này mình sẽ cho các bạn thấy mình đã thất bại thế nào khi phỏng vấn tại FPT. Có thể chúng ta thường xuyên sử dụng chúng trong những project của công ty hay của cá nhân. Nhưng hầu như các bạn quên đi kiến thức cơ bản về chúng. Để rồi có một ngày bạn chợt nhận ra rằng. Mình chẳng hiểu gì hết. Chỉ là copy/paste.

 Okay, giờ mình sẽ bắt đầu cùng các bạn đi tìm hiểu về chủ đề "Contrustor và class" qua một bài viết của tác giả Tania Rascia. Các bạn có thể bỏ qua phần giới thiệu hay các phần khác nhưng phần "constructor function và class." thì các bạn đừng bỏ qua nhé. Vì nó là phần quan trọng nhất để hiểu bài viết này. Giúp các bạn có thể viết một class rất chuyên nghiệp.


Tham gia nhóm tác giả
Facebook: Tham gia diễn đàn javascript, reactjs 
Nhóm trao đổi về es6, javascript: es6, javascript

1 - Giới thiệu.

Javascript là một ngôn ngữ prototype-based. Mọi đối tượng hay còn gọi là object bên trong javascript đều có một thuộc tính gọi là [prototype], có thể được sử dụng để mở rộng các thuộc tính và phương thức của đối tượng trong javascript. Và trong thời gian gần đây, các nhà phát triển đã dựa trên các function để xây dựng một thiết kế mới. Đó chính là ECMAScript 2015, mà chúng ta hay gọi là ES6. Es6 kế thừa và phát huy sức mạnh để cho một cú pháp dễ dang và nhìn đẹp đẽ và có vẻ chuyên nghiệp hơn, giúp các developer javascript như chúng ta có thể phát triển dễ dàng hơn. 

2 - Class chính là Function.

Vì sao mình lại nói như vậy. Các bạn xem qua ví dụ sau để hiểu rõ hơn điều này.

// Initializing a function with a function expression
// cách khởi tạo một function 
const x = function() {}
// Initializing a class with a class expression
// cách khởi tạo một class.
const y = class {}

Và bây giờ chúng ta có thể truy cập [[Prototype]] của một đối tượng bằng phương thức Object.getPrototypeOf (). Để kiểm tra xem chúng được kiểm tra như thế nào.

Object.getPrototypeOf(x);
Output
ƒ () { [native code] }

Và cũng kiểm tra luôn class y.

Object.getPrototypeOf(y);
Output
ƒ () { [native code] }

3 - Ví dụ về constructor function và class.

Đã đi đến đây rồi thì các bạn cũng cố gắng đọc phẩn này. Vì phần này là quan trong nhất bài hôm nay. Mình sẽ viết một file về constructor function là constructor.js

constructor.js
// Initializing a constructor function
function Hero(name, level) {
    this.name = name;
    this.level = level;
}

và đây là một cấu trúc class.

class.js
// Initializing a class definition
class Hero {
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }
}

Sự khác biệt duy nhất trong cú pháp khởi tạo là sử dụng class thay vì function và gán các thuộc tính bên trong phương thức constructor (). 

4 - Add method

Thật sự bao nhiêu năm hành nghề nhìn method dạng này nó thân thuộc làm sao, nhưng khi qua class thì thấy nó sao mà nặng nhọc và khó thở :D 

constructor.js

// cách add method cho constructor function 
function Hero(name, level) {
    this.name = name;
    this.level = level;
}

// Adding a method to the constructor
Hero.prototype.greet = function() {
    return `${this.name} says hello.`;
}

Và các add method cho một class, so ez.

Với cách khai báo thế này, mình thấy thực sử đơn giản vì được thêm trực tiếp vào class. ES6, xác định phương thức là một quy trình thậm chí ngắn gọn hơn. 

class.js

class Hero {
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }

    // Adding a method to the constructor
    greet() {
        return `${this.name} says hello.`;
    }
}

Bây giờ chúng ta thử console.log(new Hero('Anonystick', 2)) chúng đều có một kết quả :

Output
Hero {name: "Anonystick", level: 1}
__proto__:
  ▶ constructor: class Hero
  ▶ greet: ƒ greet()

5 - Extending một class

Một tính năng thuận lợi của các function và classes của hàm tạo là chúng có thể được mở rộng thành các bản thiết kế đối tượng mới dựa trên function có sẵn. Điều này ngăn việc lặp lại mã cho các đối tượng tương tự nhưng cần một số tính năng bổ sung hoặc cụ thể hơn. Các hàm xây dựng mới có thể được tạo từ function khác bằng cách sử dụng phương thức call (). Trong ví dụ dưới đây, chúng tôi sẽ tạo một lớp cụ thể hơn gọi là Mage và gán các thuộc tính của Hero cho nó bằng cách sử dụng lệnh call (), cũng như thêm một thuộc tính bổ sung. 

Ví dụ: constructor.js

function Hero(name, level) {
    this.name = name;
    this.level = level;
}

// Adding a method to the constructor
Hero.prototype.greet = function() {
    return `${this.name} says hello.`;
}

// Creating a new constructor from the parent
function Mage(name, level, spell) {
    // Chain constructor with call
    Hero.call(this, name, level);

    this.spell = spell;
}

class.js

// Initializing a class
class Hero {
    constructor(name, level) {
        this.name = name;
        this.level = level;
    }

    // Adding a method to the constructor
    greet() {
        return `${this.name} says hello.`;
    }
}

// Creating a new class from the parent
class Mage extends Hero {
    constructor(name, level, spell) {
        // Chain constructor with super
        super(name, level);

        // Add a new property
        this.spell = spell;
    }
}

Mặc dù cú pháp khá khác nhau, kết quả cơ bản gần như giống nhau giữa cả hai phương thức. Nhưng class cho chúng ta một cách ngắn gọn hơn để tạo các bản thiết kế đối tượng và các hàm xây dựng mô tả chính xác hơn. Cách gọi thì cũng không khác gì nhau cho lắm. 

runcode

const hero2 = new Mage('Lejon', 2, 'Magic Missile');

Output
Mage {name: "Lejon", level: 2, spell: "Magic Missile"}
__proto__:
    ▶ constructor: ƒ Mage(name, level, spell)
   

Tham gia nhóm tác giả
Facebook: Tham gia diễn đàn javascript, reactjs 
Nhóm trao đổi về es6, javascript: es6, javascript
6 - Kết Luận.

Dù sao đi nữa tôi nghĩ tương lại react sẽ lại phổ biến và lúc đó những kiến thức như thế này mạng lại lợi ích khác biệt cho các bạn bước vào một phần của react native. Trong hướng dẫn này, chúng ta đã đi tìm hiểu về sự tương đồng và khác biệt giữa constructor function JavaScript và class trong ES6. 

Cả hai lớp và các hàm tạo đều bắt chước một mô hình thừa kế hướng đối tượng thành JavaScript, đây là ngôn ngữ kế thừa dựa trên nguyên mẫu. Hiểu kế thừa nguyên mẫu là tối quan trọng để trở thành một nhà phát triển JavaScript hiệu quả. Làm quen với các lớp là vô cùng hữu ích, vì các thư viện JavaScript phổ biến như React sử dụng cú pháp lớp thường xuyên. 

Bài viết tham khảo:

https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e

https://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript