2. Xây dựng chương trình chuyển đổi nhiệt độ từ độ C sang độ F bằng cách trả về giá trị từ hàm
function toFahrenheit[celsius] {
return [celsius * 9/5 + 32];
}
document.write["Temperature in Fahrenheit is " +
toFahrenheit[45]];
nam tính
Theo
31 Tháng tám 2019
·
1 phút đọc
Triển khai các giao diện trong JavaScript
Đầu tiên tôi sẽ xác định đối tượng giao diện của mình
var PersonInterface = {
name: String,
age: Number,
say: Function
}
Bây giờ chức năng thực hiện giao diện
function implements[interface, _descriptors, _class]{
var props = Object.getOwnPropertyNames[interface],
descriptors = Object.getOwnPropertyDescriptors[interface],
errMsg = `${_class} wrongly implements interface,`;
props.map[prop => {
if[!_descriptors[prop]]{
throw Error[`${errMsg} ${prop} not available on class`];
}
if[typeof descriptors[prop].value[] !== typeof _descriptors[prop].value]{
throw Error[`${errMsg} type must be ${typeof descriptors[prop].value}`]
}
}]
}
Bây giờ lớp Person triển khai PersonInterface, bằng cách gọi phương thức triển khai trong phạm vi của nó
function Person[]{
this.name = "tom";
this.age = 23;
this.height = 6;
this.say = function[]{}
window.implements[PersonInterface,
Object.getOwnPropertyDescriptors[this], this.constructor.name]
}
Bây giờ trong khi tạo thể hiện của lớp người, nó phải triển khai tất cả các thuộc tính & phương thức của PersonInterface nếu không nó sẽ báo lỗivar p = new Person[]
Trước hết, không có hỗ trợ trừu tượng hóa truyền thống trong JavaScript. Ít nhất, không có bất kỳ loại nào như giao diện và lớp trừu tượng. Tuy nhiên, giao diện có thể được triển khai bằng Object. tạo phương thức và nguyên mẫu. Để biết thêm thông tin, truy cập vào đây
Giao diện đối tượng cho phép bạn tạo mã chỉ định phương thức nào lớp phải triển khai mà không cần phải xác định cách các phương thức này được triển khai. Các giao diện chia sẻ một không gian tên với các lớp và đặc điểm, vì vậy chúng có thể không sử dụng cùng tên
Trong thực tế, các giao diện phục vụ hai mục đích bổ sung
- Để cho phép các nhà phát triển tạo các đối tượng của các lớp khác nhau có thể được sử dụng thay thế cho nhau vì chúng triển khai cùng một hoặc nhiều giao diện. Một ví dụ phổ biến là nhiều dịch vụ truy cập cơ sở dữ liệu, nhiều cổng thanh toán hoặc các chiến lược lưu trữ khác nhau. Các triển khai khác nhau có thể được hoán đổi mà không yêu cầu bất kỳ thay đổi nào đối với mã sử dụng chúng
- Để cho phép một hàm hoặc phương thức chấp nhận và hoạt động trên một tham số phù hợp với giao diện, trong khi không quan tâm đối tượng có thể làm gì khác hoặc nó được triển khai như thế nào. Các giao diện này thường được đặt tên như
Iterable
,Cacheable
,Renderable
, v.v. để mô tả tầm quan trọng của hành vi
https. //www. php. net/manual/vi/ngôn ngữ. oop5. giao diện. php
JavaScript có giao diện không?
Không có khái niệm “lớp này phải có các chức năng này” [nghĩa là không có giao diện nào], bởi vì
- Kế thừa JavaScript dựa trên các đối tượng, không phải các lớp. Đó không phải là vấn đề lớn cho đến khi bạn nhận ra
- JavaScript là một ngôn ngữ được nhập cực kỳ động — bạn có thể tạo một đối tượng bằng các phương thức phù hợp để làm cho đối tượng tuân theo giao diện, và sau đó xác định tất cả nội dung đã làm cho nó tuân thủ. Sẽ rất dễ dàng để phá vỡ hệ thống loại - thậm chí vô tình. - rằng sẽ không đáng để thử và tạo một hệ thống loại ngay từ đầu
Thay vào đó, JavaScript sử dụng cái được gọi là gõ vịt. [Nếu nó đi như vịt, và kêu quạc quạc như vịt, theo như JS quan tâm, nó là vịt. ] Nếu đối tượng của bạn có các phương thức quack[]
, walk[]
và fly[]
, mã có thể sử dụng nó ở bất cứ nơi nào nó mong đợi một đối tượng có thể walk[]
, quack[]
và fly[]
mà không yêu cầu triển khai một số giao diện “Duckable”. Giao diện chính xác là tập hợp các chức năng mà mã sử dụng [và các giá trị trả về từ các chức năng đó] và với kiểu gõ vịt, bạn sẽ nhận được giao diện đó miễn phí
https. // stackoverflow. com/a/3710367
Ghi chú. JavaScript có từ dành riêng
module.exports = class MyInterface {
/**
* @param {string} var1
* @param {string} var2
*
* @return {string}
*/
firstMethod [var1, var2] {}
/**
* @return {string}
*/
secondMethod [] {}
/**
* @param {string} var1
*/
thirdMethod [var1] {}
}
3 trong trường hợp họ muốn triển khai các giao diệnDuck Typing có đủ để thay thế tất cả các giao diện không?
Theo ý kiến cá nhân của tôi, không
Gần đây, để nâng cao kiến thức thực tế về JavaScript, tôi đã làm việc trên cả hai dự án JavaScript và TypeScript. Việc thiếu giao diện gây khó khăn cho việc triển khai mọi thứ trong JavaScript mà tôi đã nghĩ đến trong kiến trúc PHP. Tôi cũng đã bắt đầu, với tư cách là một dự án thực hành, cố gắng sao chép một số gói PHP nhỏ nhất định trong JavaScript nhưng thường xuyên gặp sự cố là JavaScript thiếu các giao diện trong khi PHP thì không.
Đây là lúc tôi nảy ra ý tưởng tạo “giao diện” của riêng mình bằng JavaScript
Tạo “giao diện” trong JavaScript
Điều đầu tiên tôi làm là tạo một lớp mới với Giao diện là hậu tố trong tên lớp. Điều này sẽ giúp bạn phân biệt đâu là triển khai và đâu là giao diện khi xem qua các tệp. Trong trường hợp này, hãy gọi lớp của chúng ta là
module.exports = class MyInterface {
/**
* @param {string} var1
* @param {string} var2
*
* @return {string}
*/
firstMethod [var1, var2] {}
/**
* @return {string}
*/
secondMethod [] {}
/**
* @param {string} var1
*/
thirdMethod [var1] {}
}
4module.exports = class MyInterface {
}
Sau đó, tôi đã tạo tất cả các phương thức mà tôi muốn những người triển khai thực hiện nhưng đã tạo chúng dưới dạng các phương thức trống
module.exports = class MyInterface {
/**
* @param {string} var1
* @param {string} var2
*
* @return {string}
*/
firstMethod [var1, var2] {}
/**
* @return {string}
*/
secondMethod [] {}
/**
* @param {string} var1
*/
thirdMethod [var1] {}
}
Bước tiếp theo là “triển khai” giao diện. Những gì chúng tôi thực sự đang làm là mở rộng lớp
module.exports = class MyInterface {
/**
* @param {string} var1
* @param {string} var2
*
* @return {string}
*/
firstMethod [var1, var2] {}
/**
* @return {string}
*/
secondMethod [] {}
/**
* @param {string} var1
*/
thirdMethod [var1] {}
}
4, nhưng nếu chúng tôi cố gắng sử dụng các phương thức của lớp triển khai và chúng tôi không triển khai chúng, điều đó sẽ gây ra sự cố vì sẽ không có hành động nào xảy ra trên các lệnh gọi phương thứcconst MyInterface = require['./MyInterface']
module.exports = class MyImplementation extends MyInterface {
myVar
constructor [theVar]
{
this.myVar = theVar
}
/**
* @inheritDoc
*/
firstMethod [var1, var2]
{
return var1 + var2
}
/**
* @inheritDoc
*/
secondMethod []
{
return 'secondMethod'
}
/**
* @inheritDoc
*/
thirdMethod [var1]
{
this.myVar = var1
}
}
Tôi biết đây không phải là một giải pháp hoàn hảo, nhưng tôi thấy nó đủ tốt để giải quyết các vấn đề về triển khai thiết kế. Điều này sẽ cho phép bạn cũng đặt kiểu trả về cho giao diện ngay cả khi bạn đang triển khai. Nó cũng sẽ không cho phép bạn cố gắng khởi tạo lớp giao diện vì không có hàm tạo nào được định nghĩa
/**
* {MyInterface} myObject
*/
const myFunction = [] => {
return new MyImplementation[]
}
Tôi hoàn toàn biết rằng có nhiều cách để giải quyết vấn đề này và lật đổ hệ thống loại. Tôi chỉ viết bài đăng này để bất kỳ ai muốn thử đưa giao diện vào thiết kế JavaScript của họ đều có thể có cách để thực hiện điều đó