Hàm tạo thông tin javascript

Trong Javascript, muốn khởi tạo 1 khuôn thực thể [đối tượng thể hiện], ta sẽ bắt đầu với việc xây dựng 1 khuôn mẫu [hàm tạo] và sau đó sử dụng từ khóa

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
4

Bản mẫu đó, có thể là 1 hàm tạo [cách cũ] hoặc 1 lớp [từ ECMAScript 2015]

Ví dụ

Cách 1. Use constructor function

// Tạo các thuộc tính [property]
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
// Thêm vào các phương thức [method]
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// Khởi tạo 1 instance object
let milu = new Dog['Milu','Black','Becgie'];

milu.bark[] // Milu barks: Go Go Go

Cách 2. Use Class

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go

Nhưng đôi khi, mình cũng bắt gặp 1 cách khởi động khác

Cách 3

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go

Vì vậy, 3 cách làm này có gì giống nhau và khác nhau. Cách làm nào là tiện lợi và chuẩn nhất?

Để trả lời thì chúng ta sẽ hiểu điều gì đã xảy ra khi sử dụng từ khóa

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
4

Khi dùng

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
4 để tạo 1 instance object thì xảy ra các lần thứ sau

  1. Create a new Object, empty
  2. Trỏ thuộc tính [[Prototype]] [aka
    class Dog {
        // Tạo các thuộc tính [property]
        constructor[name, color, type] {
            this.name = name;
            this.color = color;
            this.type = type
        }
    
        // Thêm vào các phương thức [method]
        bark[] {
            console.log[`${this.name} barks: Go Go Go`]
        }
    }
    
    let milu = new Dog['Milu', 'Black', 'Becgie'];
    
    milu.bark[] // Milu barks: Go Go Go
    
    7] của Object null này đối với thuộc tính
    class Dog {
        // Tạo các thuộc tính [property]
        constructor[name, color, type] {
            this.name = name;
            this.color = color;
            this.type = type
        }
    
        // Thêm vào các phương thức [method]
        bark[] {
            console.log[`${this.name} barks: Go Go Go`]
        }
    }
    
    let milu = new Dog['Milu', 'Black', 'Becgie'];
    
    milu.bark[] // Milu barks: Go Go Go
    
    8 của hàm tạo
  3. Thực hiện chức năng xây dựng, với giá trị
    class Dog {
        // Tạo các thuộc tính [property]
        constructor[name, color, type] {
            this.name = name;
            this.color = color;
            this.type = type
        }
    
        // Thêm vào các phương thức [method]
        bark[] {
            console.log[`${this.name} barks: Go Go Go`]
        }
    }
    
    let milu = new Dog['Milu', 'Black', 'Becgie'];
    
    milu.bark[] // Milu barks: Go Go Go
    
    9 được gán là đối tượng chính rỗng vừa tạo
  4. Hàm kết thúc, trả về Đối tượng mới vừa tạo nếu như hàm xây dựng không trả về 1 Đối tượng không null. Còn nếu có thì sẽ trả về đối tượng không null đó

Please check check by how to done the times of the step to started 1 instance object

// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]

Quy trình trên thể hiện rằng. instance object kế thừa các phương thức từ. nguyên mẫu của hàm tạo hoặc lớp. Còn lại các thuộc tính sẽ có được bằng cách thực hiện chức năng xây dựng với giá trị của

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9 chính là đối tượng thể hiện đó

Đây là điểm làm nên sự khác biệt giữa Cách 1 và Cách 3. Ở Cách 3, các phương thức được thêm thẳng vào đối tượng thể hiện. Làm điều đó nếu thay đổi

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
8 của hàm tạo thì các phương thức được thêm trực tiếp như vậy sẽ không thay đổi

// Tạo các thuộc tính [property]
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
// Thêm vào các phương thức [method]
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// Khởi tạo 1 instance object
let milu = new Dog['Milu','Black','Becgie'];

milu.bark[] // Milu barks: Go Go Go
2

Vậy Cách 1 có khác Cách 2 không? . Đối tượng sơ thẩm được tạo theo Cách 1 hay Cách 2 đều sẽ kế thừa các phương thức từ

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
8 của bản gốc, với các thuộc tính [và giá trị của từng thuộc tính] có được bằng cách thực thi hàm tạo

Dễ thấy ở Cách 2, không có từ gì liên quan đến. nguyên mẫu. Tuy nhiên, bản chất là tất cả các phương thức được khai báo trong 1 lớp đều đã được thêm vào. nguyên mẫu của lớp đó. Việc sử dụng cú pháp

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
3 sẽ tiện lợi hơn, gọn gàng dễ hiểu hơn, nhưng cũng sẽ giảm thiểu tường minh hơn

Dù vậy, vấn đề vẫn chưa dừng lại ở đó. Từ khóa

class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9 cùng sự xuất hiện của
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
5 khiến mọi thứ phức tạp hơn một chút

Cố gắng viết lại các phương thức khai báo ở Cách 1 và Cách 3, sử dụng

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
5 như sau

Cách 1

// Tạo các thuộc tính [property]
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
// Thêm vào các phương thức [method]
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// Khởi tạo 1 instance object
let milu = new Dog['Milu','Black','Becgie'];

milu.bark[] // Milu barks: Go Go Go
8

Cách 3

// Tạo các thuộc tính [property]
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
// Thêm vào các phương thức [method]
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// Khởi tạo 1 instance object
let milu = new Dog['Milu','Black','Becgie'];

milu.bark[] // Milu barks: Go Go Go
9

Tại sao Cách 3 hoạt động lại đúng, còn Cách 1 lại không?

Lý do do

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
5 không xác định được
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9, mà sẽ quay ngược lại để tìm giá trị của
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9 tại thời điểm
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
5 được công bố. Với Cách 1, tại thời điểm khai báo,
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9 có giá trị là
// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]
2 hoặc
// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]
3, do đó
// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]
4 là
// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]
5. Trong khi đó với Cách mạng 3, thời điểm khai báo chính là Bước 3 khi từ khóa
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
4 làm việc, lúc đó
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9 được gán giá trị chính là đối tượng
// Vẫn là constructor function con chó:
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type
}
Dog.prototype.bark = function [] {
    console.log[`${this.name} barks: Go Go Go`]
}

// 1. Tạo một Object mới, trống rỗng
let milu = {}

// 2. Trỏ thuộc tính [[Prototype]] [aka `.__proto__`] của Object rỗng này tới thuộc tính `.prototype` của constructor function
milu.__proto__ = Dog.prototype

// 3. Thực hiện constructor function, với giá trị this được gán là chính Object rỗng vừa tạo
Dog.call[milu,'Milu','Black','Becgie']

// 4. Kết quả chúng ta có 1 instance object là milu "được tạo ra thủ công"
console.log[milu]
milu.bark[]
8 rồi. Làm như vậy cách 3 sẽ hoạt động đúng

Còn với việc khai báo bằng

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
3 [Cách 2] thì sẽ không cần quan tâm đến vấn đề này, do nó không sử dụng
function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
5

Kết luận. Cú pháp

function Dog[name, color, type] {
    this.name = name;
    this.color = color;
    this.type = type

    this.bark = function [] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
3 tiện lợi hơn nhiều khi thiết lập hướng đối tượng trong Javascript. Nếu bạn vẫn quyết định sử dụng các cú pháp cũ, cần xác định nguyên tắc kế thừa bằng nguyên mẫu và cách sử dụng
class Dog {
    // Tạo các thuộc tính [property]
    constructor[name, color, type] {
        this.name = name;
        this.color = color;
        this.type = type
    }

    // Thêm vào các phương thức [method]
    bark[] {
        console.log[`${this.name} barks: Go Go Go`]
    }
}

let milu = new Dog['Milu', 'Black', 'Becgie'];

milu.bark[] // Milu barks: Go Go Go
9

Chủ Đề