HomeLập trìnhJavaScriptLập trình hướng...

Lập trình hướng đối tượng trong JavaScript – Được giải thích bằng các ví dụ


JavaScript không phải là ngôn ngữ hướng đối tượng dựa trên lớp. Nhưng nó vẫn có cách sử dụng lập trình hướng đối tượng (OOP).

Trong hướng dẫn này, tôi sẽ giải thích OOP và chỉ cho bạn cách sử dụng nó.

Theo Wikipedia, lập trình dựa trên lớp là

một phong cách lập trình hướng đối tượng (OOP) trong đó kế thừa xảy ra thông qua việc xác định các lớp đối tượng, thay vì kế thừa chỉ xảy ra thông qua các đối tượng

Mô hình phổ biến nhất của OOP là dựa trên lớp.

Nhưng như tôi đã đề cập, JavaScript không phải là ngôn ngữ dựa trên phân loại – nó là ngôn ngữ dựa trên nguyên mẫu.

Theo tài liệu của Mozilla:

Một ngôn ngữ dựa trên nguyên mẫu có khái niệm về một đối tượng nguyên mẫu, một đối tượng được sử dụng làm mẫu để từ đó lấy các thuộc tính ban đầu cho một đối tượng mới.

Hãy xem mã này:

let names = {
    fname: "Dillion",
    lname: "Megida"
}
console.log(names.fname);
console.log(names.hasOwnProperty("mname"));
// Expected Output
// Dillion
// false

biến đối tượng names chỉ có hai thuộc tính – fnamelname . Không có phương pháp nào cả.

Vì vậy, nơi nào hasOwnProperty đến từ?

Vâng, nó đến từ Object nguyên mẫu.

Hãy thử ghi nội dung của biến vào bảng điều khiển:

console.log(names);

Khi bạn mở rộng kết quả trong bảng điều khiển, bạn sẽ nhận được điều này:

1-1
console.log(tên)

Lưu ý tài sản cuối cùng – __proto__? Hãy thử mở rộng nó:

2-1
Thuộc tính __proto__ của tên

Bạn sẽ thấy một tập hợp các thuộc tính bên dưới Object người xây dựng. Tất cả các tài sản này đến từ toàn cầu Object nguyên mẫu. Nếu bạn nhìn kỹ, bạn cũng sẽ nhận thấy ẩn của chúng tôi hasOwnProperty .

Nói cách khác, tất cả các đối tượng đều có quyền truy cập vào Objectnguyên mẫu của. Họ không sở hữu các thuộc tính này, nhưng được cấp quyền truy cập vào các thuộc tính trong nguyên mẫu.

Các __proto__ tài sản

Điều này trỏ đến đối tượng được sử dụng làm nguyên mẫu.

Đây là thuộc tính trên mọi đối tượng cho phép nó truy cập vào Object prototype tài sản.

Đọc thêm  Mô hình đồng thời JavaScript và vòng lặp sự kiện

Mọi đối tượng đều có thuộc tính này theo mặc định, thuộc tính này đề cập đến Object Protoype trừ khi được cấu hình theo cách khác (nghĩa là khi đối tượng __proto__ được trỏ đến một nguyên mẫu khác).

sửa đổi __proto__ tài sản

Thuộc tính này có thể được sửa đổi bằng cách tuyên bố rõ ràng rằng nó nên tham chiếu đến một nguyên mẫu khác. Các phương pháp sau đây được sử dụng để đạt được điều này:

Object.create()

function DogObject(name, age) {
    let dog = Object.create(constructorObject);
    dog.name = name;
    dog.age = age;
    return dog;
}
let constructorObject = {
    speak: function(){
        return "I am a dog"
    }
}
let bingo = DogObject("Bingo", 54);
console.log(bingo);

Trong bảng điều khiển, đây là những gì bạn có:

3-1
console.log(bingo)

chú ý __proto__ tài sản và speak phương pháp?

Object.create sử dụng đối số được truyền cho nó để trở thành nguyên mẫu.

new từ khóa

function DogObject(name, age) {
    this.name = name;
    this.age = age;
}
DogObject.prototype.speak = function() {
    return "I am a dog";
}
let john = new DogObject("John", 45);

john‘S __proto__ tài sản được hướng đến DogObjectnguyên mẫu của. Nhưng hãy nhớ, DogObjectnguyên mẫu của là một đối tượng (cặp khóa và giá trị), do đó nó cũng có một __proto__ tài sản đề cập đến toàn cầu Object nguyên mẫu.

Kỹ thuật này được gọi là CHUỖI NGUYÊN NHÂN.

Lưu ý rằng: các new cách tiếp cận từ khóa làm điều tương tự như Object.create() nhưng chỉ làm cho nó dễ dàng hơn vì nó tự động làm một số việc cho bạn.

Và vì thế…

Mọi đối tượng trong Javascript đều có quyền truy cập vào Objectnguyên mẫu của theo mặc định. Nếu được định cấu hình để sử dụng nguyên mẫu khác, hãy nói prototype2sau đó prototype2 cũng sẽ có quyền truy cập vào nguyên mẫu của Đối tượng theo mặc định, v.v.

Kết hợp đối tượng + chức năng

bạn có thể bối rối bởi thực tế là DogObject là một hàm (function DogObject(){}) và nó có các thuộc tính được truy cập bằng một ký hiệu dấu chấm. Điều này được gọi là một chức năng kết hợp đối tượng.

Khi các hàm được khai báo, mặc định chúng được gán rất nhiều thuộc tính kèm theo. Hãy nhớ rằng hàm cũng là đối tượng trong kiểu dữ liệu JavaScript.

Bây giờ, cả lớp

JavaScript đã giới thiệu class từ khóa trong ECMAScript 2015. Nó làm cho JavaScript giống như một ngôn ngữ OOP. Nhưng nó chỉ là đường tổng hợp đối với kỹ thuật tạo mẫu hiện có. Nó tiếp tục tạo mẫu trong nền nhưng làm cho phần thân bên ngoài trông giống như OOP. Bây giờ chúng ta sẽ xem làm thế nào điều đó có thể xảy ra.

Đọc thêm  Cách làm việc với chuỗi trong JavaScript – Mẹo để nối chuỗi hiệu quả

Ví dụ sau đây là cách sử dụng chung của một class trong JavaScript:

class Animals {
    constructor(name, specie) {
        this.name = name;
        this.specie = specie;
    }
    sing() {
        return `${this.name} can sing`;
    }
    dance() {
        return `${this.name} can dance`;
    }
}
let bingo = new Animals("Bingo", "Hairy");
console.log(bingo);

Đây là kết quả trong bảng điều khiển:

5-1
console.log(bingo)

Các __proto__ tài liệu tham khảo Animals nguyên mẫu (từ đó tham chiếu đến Object nguyên mẫu).

Từ đó, chúng ta có thể thấy rằng hàm tạo xác định các tính năng chính trong khi mọi thứ bên ngoài hàm tạo (sing()dance()) là các tính năng thưởng (nguyên mẫu).

Trong nền, sử dụng new cách tiếp cận từ khóa, ở trên dịch là:

function Animals(name, specie) {
    this.name = name;
    this.specie = specie;
}
Animals.prototype.sing = function(){
    return `${this.name} can sing`;
}
Animals.prototype.dance = function() {
    return `${this.name} can dance`;
}
let Bingo = new Animals("Bingo", "Hairy");

phân lớp

Đây là một tính năng trong OOP trong đó một lớp kế thừa các tính năng từ lớp cha nhưng sở hữu các tính năng bổ sung mà lớp cha không có.

Ví dụ, ý tưởng ở đây là bạn muốn tạo một những con mèo lớp. Thay vì tạo lớp từ đầu – nêu rõ Tên, lứa tuổiloài thuộc tính một lần nữa, bạn sẽ kế thừa những thuộc tính đó từ cha mẹ loài vật lớp.

Cái này những con mèo lớp sau đó có thể có các thuộc tính bổ sung như màu râu.

Hãy xem cách các lớp con được thực hiện với class.

Ở đây, chúng ta cần một cha mẹ mà lớp con kế thừa từ đó. Kiểm tra đoạn mã sau:

class Animals {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sing() {
        return `${this.name} can sing`;
    }
    dance() {
        return `${this.name} can dance`;
    }
} 
class Cats extends Animals {
    constructor(name, age, whiskerColor) {
        super(name, age);
        this.whiskerColor = whiskerColor;
    }
    whiskers() {
        return `I have ${this.whiskerColor} whiskers`;
    }
}
let clara = new Cats("Clara", 33, "indigo");

Với những điều trên, chúng tôi nhận được các kết quả đầu ra sau:

console.log(clara.sing());
console.log(clara.whiskers());
// Expected Output
// "Clara can sing"
// "I have indigo whiskers"

Khi bạn đăng nội dung của clara ra trong bảng điều khiển, chúng ta có:

Đọc thêm  23 trang web miễn phí để học JavaScript năm 2022

6-1
bảng điều khiển.log (clara)

Bạn sẽ nhận thấy rằng clara có một __proto__ thuộc tính tham chiếu hàm tạo Cats và có quyền truy cập vào whiskers() phương pháp. Cái này __proto__ tài sản cũng có một __proto__ thuộc tính tham chiếu hàm tạo Animals nhờ đó có được quyền truy cập vào sing()dance(). nameage là những thuộc tính tồn tại trên mọi đối tượng được tạo từ this.

Sử dụng Object.create phương pháp tiếp cận, ở trên chuyển thành:

function Animals(name, age) {
    let newAnimal = Object.create(animalConstructor);
    newAnimal.name = name;
    newAnimal.age = age;
    return newAnimal;
}
let animalConstructor = {
    sing: function() {
        return `${this.name} can sing`;
    },
    dance: function() {
        return `${this.name} can dance`;
    }
}
function Cats(name, age, whiskerColor) {
    let newCat = Animals(name, age);
    Object.setPrototypeOf(newCat, catConstructor);
    newCat.whiskerColor = whiskerColor;
    return newCat;
}
let catConstructor = {
    whiskers() {
        return `I have ${this.whiskerColor} whiskers`;
    }
}
Object.setPrototypeOf(catConstructor, animalConstructor);
const clara = Cats("Clara", 33, "purple");
clara.sing();
clara.whiskers();
// Expected Output
// "Clara can sing"
// "I have purple whiskers"

Object.setPrototypeOf là một phương thức có hai đối số – đối tượng (đối số thứ nhất) và nguyên mẫu mong muốn (đối số thứ hai).

Từ những điều trên, các Animals hàm trả về một đối tượng với animalConstructor như nguyên mẫu. Các Cats hàm trả về một đối tượng với catConstructor như nó là nguyên mẫu. catConstructor mặt khác, được đưa ra một nguyên mẫu của animalConstructor.

Do đó, động vật bình thường chỉ có quyền truy cập vào animalConstructor nhưng mèo có quyền truy cập vào catConstructoranimalConstructor.

kết thúc

JavaScript tận dụng bản chất nguyên mẫu của nó để chào đón các nhà phát triển OOP đến với hệ sinh thái của nó. Nó cũng cung cấp những cách dễ dàng để tạo nguyên mẫu và sắp xếp dữ liệu liên quan.

Các ngôn ngữ OOP thực sự không thực hiện tạo mẫu trong nền – chỉ cần lưu ý điều đó.

Xin chân thành cảm ơn khóa học của Will Sentance về Frontend Masters – JavaScript: The Hard Part of Object Oriented JavaScript. Tôi đã học được mọi thứ bạn thấy trong bài viết này (cộng với một chút nghiên cứu bổ sung) từ khóa học của anh ấy. Bạn nên kiểm tra xem nó ra.

Bạn có thể đánh tôi trên Twitter tại iamdillion cho bất kỳ câu hỏi hoặc đóng góp.

Cảm ơn vì đã đọc : )

Tài nguyên hữu ích





Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status