Thành viên lớp javascript

JavaScript vốn không phải là một ngôn ngữ nhẹ nhàng hoàn toàn theo hướng đối tượng hay hướng cấu trúc, mà nó lại thuộc dạng “nửa kia mỡ”. Đối với lập trình hướng cấu trúc trong JavaScript thì tạm thời mình không nói tới, nhưng lập trình hướng đối tượng trong JavaScript thì đúng là “chán”. By mang tiếng là có hỗ trợ hướng đối tượng, nhưng nó lại không hỗ trợ hết các tính chất của OOP, làm cho nhà phát triển cảm thấy bối rối khi code OOP với JavaScript

Qua bài viết này, chúng ta sẽ cùng nhau đi tìm hiểu về cách thiết lập hướng đối tượng trong JavaScript. Để xem nó hỗ trợ và không hỗ trợ những tính chất nào của OOP, nếu không hỗ trợ thì chúng ta có cách nào để thay thế không nhé

>> Đọc thêm. Lập trình hướng đối tượng – Hiểu cái ý đồ

lục mục

  • 1. Khởi tạo class trong JavaScript
  • 2. Thuộc tính của đối tượng trong JavaScript
  • 3. Kế thừa lớp trong JavaScript
    • 3. 1 Kế thừa hoàn toàn lớp cha
    • 3. 2 Kế thừa và ghi đè phương thức khởi dựng ở lớp cha
    • 3. 3 Kế thừa và ghi đè phương thức thông thường của lớp cha
  • 4. Sử dụng lớp trừu tượng trong JavaScript
  • 5. Sử dụng Giao diện trong JavaScript
  • 6. Tổng kết

1. Khởi tạo class trong JavaScript

Từ phiên bản javascript es6 hay còn được biết đến với cái tên là es2015, JavaScript đã bổ sung thêm khái niệm lớp, giúp nhà phát triển dễ dàng triển khai mã hướng đối tượng hơn. Về cơ bản, một lớp trong JavaScript được khai báo và sử dụng như sau

class Person {
    say [] {
        return "Hello world";
    }
}

var me = new Person[];
console.log[me.say[]]; // Hello world

Trông có vẻ ổn đấy chứ, các đối tượng trong JavaScript được khởi tạo thông qua từ khóa

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
1 giống như bao ngôn ngữ lập trình hướng các đối tượng khác. Do đó, việc khai báo lớp và khởi tạo đối tượng trong JavaScript không có gì lạ cả. Tới đây mọi thứ vẫn thuộc về

2. Thuộc tính của đối tượng trong JavaScript

Chúng ta cùng xem xét ví dụ với một lớp

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
0 có kèm theo thuộc tính
class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
1 xem thế nào nhé

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình

Trông mọi thứ vẫn ổn. JavaScript cũng hỗ trợ hàm

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
2 như các ngôn ngữ lập trình hướng đối tượng khác. Ấy à mà khoan, cứ để ý vào thân hàm
class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
2 xem

What what here?

this.name = name;

Đoạn mã trên là chúng ta đang gán tên giá trị cho thuộc tính với tên giá trị được truyền vào thông qua hàm tạo hàm. Vì vậy, câu hỏi đặt ra ở đây là thuộc tính tên này là công khai, riêng tư hay được bảo vệ?

Câu trả lời công khai. Bởi vì JavaScript không hỗ trợ đầy đủ tính năng đóng gói trong OOP, mọi thuộc tính của đối tượng đều có thể truy xuất được từ bên ngoài nếu biết chính xác tên thuộc tính là gì, điều này giống với công khai trong các ngôn ngữ lập trình

Mọi thứ bắt đầu xuất hiện rắc rối rồi, vậy có cách nào để khai báo thuộc tính cho javascript là riêng tư hay được bảo vệ không? . Tuy nhiên, bạn vẫn có thể mô phỏng các thuộc tính ở dạng riêng tư, được bảo vệ nhưng sẽ phức tạp – khuyến cáo bạn không nên cố gắng

3. Kế thừa lớp trong JavaScript

Trong Javascript, một lớp có thể kế thừa một lớp khác thông qua từ khóa

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
4

Đối với kế thừa, chúng ta sẽ lần lượt xét 3 trường hợp

  • class con only next class cha
  • class con kế thừa và ghi đè phương thức khởi tạo ở class cha
  • class con kế thừa và ghi đè các phương thức thông thường ở class cha

3. 1 Kế thừa hoàn toàn lớp cha

Các ví dụ được lấy sau, lớp

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
5 chỉ đơn giản là mở rộng từ lớp
class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
0

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
0

Việc kế hoạch một lớp con chỉ kế thừa lớp cha mà không ghi đè bất kỳ phương thức nào có vẻ ổn định, không có gì đáng bàn luận

3. 2 Kế thừa và ghi đè phương thức khởi dựng ở lớp cha

Vẫn là ví dụ tương tự như trên, nhưng giờ ở lớp

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
5 mình sẽ ghi đè phương thức khởi tạo ở lớp
class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
0 xem thế nào nhé

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
3

Nhìn đoạn mã có vẻ ổn, nhưng thực chất bạn sẽ nhận ra lỗi thế này

lỗi. Lỗi loại chưa bắt được. Không thể đặt thuộc tính 'tên' của không xác định

Nguyên nhân là đối với JavaScript, nếu bạn muốn ghi đè phương thức khởi tạo của lớp cha thì ở lớp con phải gọi hàm

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
9

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
9 là hàm tham chiếu tới phương thức ở lớp cha

Ví dụ trên cần phải được thay đổi lại như sau

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
6

Hải lưu ý quan trọng
– Thứ 1. Nếu trong lớp bạn không khai báo hàm tạo phương thức thì mặc định nó luôn có một hàm tạo lớp với thân hàm rỗng. Vì vậy, trong bất kỳ trường hợp nào, nếu muốn ghi đè phương thức khởi tạo ở lớp cha [cho dù lớp cha không được bạn khai báo hàm khởi tạo] thì bạn vẫn phải gọi hàm super[].
– Thứ 2. Hàm super[] phải được gọi trước khi bạn chuyển tới

this.name = name;
1 trong thân hàm, nếu không sẽ bị lỗi tham chiếu tới lớp cha. Cách tốt nhất là gọi hàm super[] ngay dòng đầu tiên của thân hàm constructor[].

3. 3 Kế thừa và ghi đè phương thức thông thường của lớp cha

Vẫn là ví dụ tương tự, giờ ở lớp

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
5 mình sẽ thử ghi ngược phương thức
this.name = name;
3 xem thế nào

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
0

Đoạn mã trên chạy ngon, với phương thức

this.name = name;
3 đã trả về “
this.name = name;
5” thay vì “
this.name = name;
6” như lúc trước. Có nghĩa là việc ghi đè phương thức thông thường ở lớp cha chỉ đơn giản là tạo một phương thức khác ở lớp con có tên trùng với phương thức muốn ghi đè

Ấy khoan, thế nào nếu muốn ghi đè, nhưng vẫn thực hiện logic ở phương thức ở lớp cha thì làm thế nào?

Ví dụ

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
7

Trải qua 3 trường hợp kế thừa trong JavaScript thì mình thấy nó cũng ổn, không có điều gì đặc biệt lắm

4. Sử dụng lớp trừu tượng trong JavaScript

Thật buồn, hiện tại [2019] thì JavaScript không hỗ trợ khái niệm lớp trừu tượng. Nhưng may mắn là chúng ta vẫn có thể dễ dàng mô phỏng một lớp trừu tượng dựa trên các tính chất của nó mà chúng ta vẫn thường hiểu là

  • Lớp trừu tượng không thể sử dụng để khởi động
  • Các lớp mở rộng lớp trừu tượng đều phải triển khai một số phương thức cụ thể và thuộc tính do lớp trừu tượng quy định

Các bạn có thể tham khảo lớp

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
00 trong ví dụ dưới đây để biết cách mô phỏng một lớp trừu tượng trong JavaScript

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
9

class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
01 sẽ trả về tên lớp được khởi tạo sau từ khóa
class Person {
    constructor [name] {
        this.name = name
    }

    say [] {
        return "My name is " + this.name;
    }
}

var me = new Person["Bình"];
me.say []; // My name is Bình
1. Bạn có thể tham khảo thêm ở đây .

5. Sử dụng Giao diện trong JavaScript

Đến lớp trừu tượng mà JavaScript còn không hỗ trợ thì bạn nghĩ sao về giao diện. Cách tốt nhất là bạn nên quên khái niệm giao diện đi nếu bạn đang lập trình với JavaScript, đơn giản là nó không hỗ trợ giao diện và việc mô phỏng một giao diện [giống như mình mô phỏng lớp trừu tượng ở trên] quá phức tạp

6. Tổng kết

In set the direction object has 4 tính chất quan trọng là. tính đóng gói, tính hiển thị, tính đa hình, tính kế thừa. Thì với JavaScript, các tính chất trên được thể hiện ở mức độ như sau

  • Tính đóng gói. Hỗ trợ kém
  • Tính năng hiển thị đối tượng. Hỗ trợ kèm theo
  • Tính đa hình. Tốt
  • Kế thừa kế thừa. Tốt

Đánh giá tổng quan. 5/10 điểm. Với số lượng khoảng cách khoảng này, bạn vẫn có thể thiết lập hướng đối tượng trình với JavaScript được, tuy nhiên sẽ gặp khó khăn trong việc mô phỏng tính đóng gói và tính đối tượng

Có cách nào cải thiện khả năng hướng đối tượng của JavaScript không?

Câu trả lời là có, bạn có thể sử dụng ngôn ngữ JavaScript tiền tệ [các ngôn ngữ sẽ biên dịch ra mã JavaScript rồi mới chạy] như TypeScript không có giới hạn. TypeScript cung cấp cú pháp hướng đối tượng trong JavaScript sáng hơn, nhưng cuối cùng TypeScript sẽ được biên dịch thành mã JavaScript để chạy

JavaScript vốn sida vậy, theo bạn nó đang có để theo học hay không?

Bài viết được viết dựa trên kinh nghiệm cá nhân, rất mong nhận được sự góp ý của các bạn

Chúc các bạn học tập hiệu quả

Facebook

Twitter

Pinterest

WhatsApp

Bài viết trước Những điều khiến nhà phát triển thường FA

Bài viết tiếp theo Tóm gọn JavaScript es6 trong 10 phút

Phạm Bình

https. //phuongbinh. mạng lưới

Mình muốn chia sẻ những kiến ​​thức mà mình học được trong quá trình làm việc và phát triển, với hy vọng sẽ giúp ích cho bạn đọc - như cách mà mình học được từ việc đọc các blog khác

Chủ Đề