Javascript có nghĩa là một ngôn ngữ dựa trên nguyên mẫu?


255

Một trong những lợi thế lớn với Javascript được cho là nó là ngôn ngữ dựa trên nguyên mẫu.

Nhưng điều đó có nghĩa là Javascript dựa trên nguyên mẫu và tại sao đó lại là một lợi thế?


3
Câu trả lời này giải thích mọi thứ bạn cần biết về thừa kế nguyên mẫu: stackoverflow.com/a/16872315/783743
Aadit M Shah

Câu trả lời:


291

Kế thừa nguyên mẫu là một hình thức tái sử dụng mã hướng đối tượng . Javascript là một trong những ngôn ngữ hướng đối tượng [chính thống] duy nhất sử dụng kế thừa nguyên mẫu. Hầu như tất cả các ngôn ngữ hướng đối tượng khác là cổ điển.

Trong kế thừa cổ điển , lập trình viên viết một lớp, định nghĩa một đối tượng. Nhiều đối tượng có thể được khởi tạo từ cùng một lớp, vì vậy bạn có mã ở một nơi mô tả một số đối tượng trong chương trình của bạn. Các lớp sau đó có thể được tổ chức thành một hệ thống phân cấp, tiếp tục sử dụng lại mã. Mã chung hơn được lưu trữ trong một lớp cấp cao hơn, từ đó các lớp cấp thấp hơn kế thừa. Điều này có nghĩa là một đối tượng đang chia sẻ mã với các đối tượng khác cùng lớp, cũng như với các lớp cha của nó.

Trong hình thức thừa kế nguyên mẫu, các đối tượng kế thừa trực tiếp từ các đối tượng khác. Tất cả các doanh nghiệp về các lớp học đi. Nếu bạn muốn một đối tượng, bạn chỉ cần viết một đối tượng. Nhưng tái sử dụng mã vẫn là một thứ có giá trị, vì vậy các đối tượng được phép liên kết với nhau theo thứ bậc. Trong javascript, mọi đối tượng đều có một liên kết bí mật đến đối tượng đã tạo ra nó, tạo thành một chuỗi. Khi một đối tượng được yêu cầu một thuộc tính mà nó không có, đối tượng cha của nó sẽ được yêu cầu ... liên tục lên chuỗi cho đến khi tìm thấy thuộc tính hoặc cho đến khi đạt được đối tượng gốc.

Mỗi hàm trong JavaScript (chính là các đối tượng) thực sự có một thành viên gọi là "nguyên mẫu", chịu trách nhiệm cung cấp các giá trị khi một đối tượng được yêu cầu chúng. Có thành viên này cho phép cơ chế xây dựng (theo đó các đối tượng được xây dựng từ các hàm) hoạt động. Thêm một thuộc tính vào nguyên mẫu của một đối tượng hàm sẽ làm cho nó có sẵn cho đối tượng được xây dựng, cũng như cho tất cả các đối tượng kế thừa từ nó.

Ưu điểm

Có thể không có một quy tắc cứng và nhanh nào về việc tại sao thừa kế nguyên mẫu là một hình thức tái sử dụng mã có lợi. Tái sử dụng mã tự nó là lợi thế và kế thừa nguyên mẫu là một cách hợp lý để đi về nó. Bạn có thể lập luận rằng kế thừa nguyên mẫu là một mô hình tái sử dụng mã khá đơn giản và mã đó có thể được sử dụng lại theo cách trực tiếp . Nhưng ngôn ngữ cổ điển chắc chắn cũng có thể thực hiện được điều này.

Sidenote: @Andrew Hedges nói rõ rằng thực sự có nhiều ngôn ngữ nguyên mẫu. Điều đáng chú ý là những người khác tồn tại, nhưng cũng đáng lưu ý rằng không ai trong số họ là bất cứ điều gì gần với chính thống. NewtonScript dường như có một lực kéo trong một thời gian, nhưng đã chết với nền tảng của nó. Cũng có thể mở rộng một số ngôn ngữ hiện đại theo cách thêm khả năng tạo mẫu.


9
Này Kelly. Trong khi JavaScript là cho đến nay các ngôn ngữ nguyên chủng phổ biến nhất, có rất nhiều người khác: en.wikipedia.org/wiki/Prototype-based_programming#Languages
Andrew Hedges

2
Này Andrew. Điểm tốt. Tôi cần phải có được rõ ràng hơn. Tôi sẽ ghi chú về nó.
keparo

3
Vui lòng đọc phần này cũng developer.mozilla.org/en/JavaScript/Guide/,
pramodc84

1
+1 cho một câu trả lời tuyệt vời. Một nhận xét nhỏ: Đối với tôi, thừa kế cổ điển có vẻ "trực tiếp" hơn nguyên mẫu. Trong thực tế, tôi thực sự thấy đối tượng nguyên mẫu chỉ là liên kết (với các đối tượng khác), trong khi trong một OOP được biên dịch, tôi coi lớp cơ sở là "kế thừa trực tiếp". Như vậy, các đối tượng nguyên mẫu được kết nối với nhau chứ không phải là kế thừa (thừa kế có phần bị làm giả). Có suy nghĩ gì không?
Tù nhân ZERO

3
@PrisonerZERO: Tôi cho rằng sự kế thừa nguyên mẫu trực tiếp hơn cổ điển. Thay vì đối tượng B trỏ đến một lớp kế thừa từ lớp mà đối tượng A trỏ tới, nó chỉ trực tiếp vào đối tượng A và nói "tôi giống như đối tượng đó, ngoại trừ ...". Điều quan trọng về sự kế thừa nguyên mẫu và điều có vẻ khó nhất đối với hầu hết mọi người là nội tâm hóa, là nó không phân biệt các thể hiện với các loại. Mỗi đối tượng là cả một loại và một thể hiện. Sự khác biệt giữa hai người là giả tạo và cố tình, và thường là một triệu chứng của việc bị mắc kẹt trong một tư duy định hướng giai cấp.
cHao

54

Một ngôn ngữ dựa trên nguyên mẫu, không tạo ra sự khác biệt giữa các lớp và các đối tượng: nó chỉ đơn giản là có các đối tượng. 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 khuôn mẫu để lấy các thuộc tính ban đầu cho một đối tượng mới. Bất kỳ đối tượng nào cũng có thể chỉ định các thuộc tính của riêng nó, khi bạn tạo nó hoặc trong thời gian chạy. Ngoài ra, bất kỳ đối tượng nào cũng có thể được liên kết làm nguyên mẫu cho một đối tượng khác , cho phép đối tượng thứ hai chia sẻ các thuộc tính của đối tượng đầu tiên.


6
Một lời giải thích rất hay, nhưng một chút sai lệch với nhận xét về "mẫu cho các thuộc tính ban đầu". Nếu bạn thay đổi nguyên mẫu SAU KHI khởi tạo một đối tượng, đối tượng đó vẫn nhận được các chức năng đó.
nickf

32

Lập trình dựa trên nguyên mẫu là một kiểu lập trình hướng đối tượng, nơi các lớp không có mặt và việc tái sử dụng hành vi (hoặc kế thừa trong các ngôn ngữ dựa trên lớp) được thực hiện bằng cách nhân bản các đối tượng hiện có làm nguyên mẫu.


Bạn vẫn cảm thấy như vậy? Bởi vì nếu vậy thì đây là lời giải thích đầu tiên để thực sự chỉ cần "nhấp chuột" với tôi.
Chazt3n

11

Ưu điểm / nhược điểm là, chúng ta có thể tạo các loại đối tượng mới trong thời gian chạy mà không cần xác định các lớp (mã tĩnh). Giống như hầu hết các tính năng, tùy thuộc vào nhà phát triển để biến nó thành một lợi thế / bất lợi.

Trên đây là có thể bởi vì các đối tượng về cơ bản là các chức năng trong tập lệnh java (đóng quá).


Các đối tượng động là một lợi ích của javascript, nhưng chúng không thực sự liên quan đến javascript là ngôn ngữ nguyên mẫu hoặc ngôn ngữ chức năng. Trong nhiều ngôn ngữ cổ điển, bạn có thể tạo các đối tượng động khi chạy. Đóng cửa có phần không liên quan, là tốt.
keparo

2
Các lớp không nhất thiết phải là một mã tĩnh - hãy xem Python, trong đó các lớp là chính các đối tượng và được xây dựng từ các siêu dữ liệu cũng là các đối tượng.
Tomasz Zieliński

6

Thay vì khai báo cấu trúc lớp, bạn có thể tạo các đối tượng cùng loại và thêm vào định nghĩa của chúng bất cứ lúc nào bạn muốn bằng cách sử dụng nguyên mẫu của đối tượng. Nó linh hoạt hơn cách làm thông thường.


6

Nếu bạn chỉ sử dụng các đối tượng trong thời gian chạy thay vì một lớp lúc biên dịch để xây dựng các đối tượng mới, thì điều này mở ra khả năng mở rộng một đối tượng mà không biết bất kỳ chi tiết nào về nó. Tất nhiên, nó có thể trở thành một bất lợi khá nhanh tùy thuộc vào cách sử dụng. Tôi không đưa ra giả định nào về ngôn ngữ ở đây, vì vậy nó có thể áp dụng cho các ngôn ngữ khác ngoài javascript không động.

myobject.prototype=unkownobject;
myobject.newproperty=1;

Bạn có thể lấy đối tượng từ bất cứ đâu; mã riêng của bạn, từ mạng, từ cơ sở dữ liệu, từ liên kết bên ngoài, v.v.

Lưu ý rằng, một ngôn ngữ không phải thực hiện kế thừa nguyên mẫu như javascript. Trong javascript, một đối tượng nguyên mẫu chỉ được chia sẻ, các thuộc tính của nó cũng nằm trong số các thừa kế. Thay thế là sao chép tất cả các thuộc tính của nguyên mẫu sang đối tượng mới. Mỗi cách tiếp cận có điểm mạnh của nó trong các tình huống khác nhau. Tôi thích thứ hai hơn nhưng đó không phải là những gì javascript làm.


6

Sau khi đọc tất cả các câu trả lời, đây là kết luận

1) Kế thừa trong đó các đối tượng được kế thừa trực tiếp từ các đối tượng khác

2) Điều đó không sử dụng các lớp

3) Cũng được gọi là lập trình dựa trên cá thể hoặc lập trình hướng mẫu không phân lớp

4) Tái sử dụng hành vi được thực hiện bằng cách nhân bản các đối tượng hiện có đóng vai trò nguyên mẫu

5) Đối tượng được sử dụng làm mẫu từ đối tượng mới có các thuộc tính ban đầu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.