Những vấn đề lập trình phổ biến nào được giải quyết tốt nhất bằng cách sử dụng các nguyên mẫu và đóng cửa?


8

Nhiều như tôi hiểu cả hai khái niệm, tôi không thể thấy làm thế nào tôi có thể tận dụng các đóng cửa và nguyên mẫu của JavaScript ngoài việc sử dụng chúng để tạo các khối giống như lớp được đóng gói và có thể giải quyết được (có vẻ như là một cách giải quyết hơn là một tài sản đối với tôi )

Các tính năng JS khác như hàm-giá trị hoặc đánh giá logic của những người không phải là booleans dễ yêu hơn nhiều ...

Những vấn đề lập trình phổ biến nào được giải quyết tốt nhất bằng cách sử dụng kế thừa và đóng cửa propotypal?


1
OO được giải quyết bằng sự kế thừa nguyên mẫu. Trong các nguyên mẫu JavaScript là cơ chế OO của bạn. Và đóng cửa là những gì bạn sử dụng để liên kết trạng thái với một chức năng. Tôi khuyên bạn nên thử node.js hoặc bất cứ thứ gì khác sử dụng logic không đồng bộ rất nhiều, bạn sẽ dễ dàng yêu thích việc đóng cửa.
Raynos

Có lẽ tôi đã không làm cho mình đủ rõ ràng - Tôi đã nhận thức được việc đạt được OO thông qua các nguyên mẫu, nhưng phải sử dụng nhiều hơn tính năng đó không? Hãy đặt một số ví dụ về logic không đồng bộ.
vemv

1
bạn làm cho nó có vẻ như đạt được OO thông qua các nguyên mẫu là một kỳ công nhỏ, "chắc chắn các nguyên mẫu phải có nhiều công dụng hơn OO"
Raynos

2
@vemv: Nguyên mẫu ở đó để cung cấp cho bạn OO. Giai đoạn = Stage. Bất cứ điều gì khác thực sự chỉ là lạm dụng.
Jan Hudec

2
@vemv họ không kỳ lạ, cộng đồng javascript chỉ làm một công việc rất nghèo tại giảng dạy mẫu Go đọc về protoypes
Raynos

Câu trả lời:


5
  1. Đóng cửa là những gì làm cho các chức năng như các giá trị hữu ích. Khi bạn đang truyền chức năng, bạn gần như chắc chắn cần nó để thực hiện một số bối cảnh. Đó là chính xác những gì đóng cửa làm.

  2. Nguyên mẫu chỉ là một phiên bản đơn giản hơn của kế thừa lớp. Thay vì có các thể hiện và các lớp (dù được đại diện bởi các thể hiện đặc biệt trong các ngôn ngữ động), bạn chỉ có các thể hiện và nguyên mẫu là lớp (và nguyên mẫu của nó là lớp cơ sở). Vì vậy, về cơ bản, chúng giải quyết các vấn đề tương tự, chỉ là các nguyên mẫu dễ thực hiện hơn (đó là lý do tại sao JavaScript chọn chúng), hơi khó sử dụng (tốt, chỉ thiếu đường cú pháp) và để lạm dụng tốt hơn hoặc xấu hơn.


"Khi truyền các hàm bạn gần như chắc chắn cần ngữ cảnh" không thực sự, hãy nhìn vào C và các con trỏ hàm của chúng, chúng không cần ngữ cảnh. Nói chung nếu bạn vượt qua các chức năng xung quanh bạn cung cấp cho các chức năng này bối cảnh họ cần. Đóng cửa chắc chắn là một cách tuyệt vời để vượt qua bối cảnh, nhưng cách xa duy nhất
Raynos

"Các nguyên mẫu dễ thực hiện hơn (đó là lý do tại sao JavaScript chọn chúng)" Đó là một tuyên bố mơ hồ (và rất có thể là sai) mà không có bất kỳ loại tham chiếu nào.
Raynos

@Raynos: trong C, chúng ta thường truyền ngữ cảnh cho các hàm thông qua một void* datađối số bị hạ thấp bởi hàm được gọi.
kevin cline

1
@Raynos: Tôi đang xem các con trỏ hàm C và chúng rất đau khi sử dụng trừ khi mã đưa chúng đi qua một khoảng trống thừa * với ngữ cảnh. Đối với các nguyên mẫu, rõ ràng chúng dễ thực hiện hơn, vì bạn chỉ có một loại đối tượng không nguyên thủy và một cách truy cập thành viên thống nhất (và không tách rời ví dụ và thành viên lớp và không có hành vi đặc biệt nào của siêu đối tượng). Mặc dù tôi không có tài liệu tham khảo rằng các nhà thiết kế ECMAScript thực sự đã chọn nguyên mẫu vì lý do này, thông dịch viên tối thiểu là mục tiêu thiết kế quan trọng, vì vậy rất có khả năng.
Jan Hudec

@JanHudec Tôi nghĩ rằng đó là một vài đơn đặt hàng có nhiều khả năng JavaScript có các nguyên mẫu vì ngôn ngữ OO nguyên mẫu Tự ảnh hưởng đến brendan khi anh ấy viết javascript.
Raynos

4

Đóng cửa không giải quyết bất kỳ vấn đề lập trình không thể giải quyết mà không có chúng. Tuy nhiên, điều này có thể nói cho bất kỳ tính năng ngôn ngữ nào không cần thiết cho tính đầy đủ của Turing, vì vậy nó không có nghĩa gì nhiều.

Hãy suy nghĩ về cách bạn phải viết lại bất kỳ mã nào sử dụng bao đóng, để không sử dụng bao đóng. Bạn có thể sẽ cung cấp cho hàm với các thuộc tính bổ sung đóng để nó có thể giữ trạng thái giữa các cuộc gọi. Mà sẽ chỉ sao chép các biến đã có trong phạm vi vào các thuộc tính cùng tên trên hàm, vì vậy nó sẽ là loại bài tập gõ không suy nghĩ khiến bạn muốn hét lên trên màn hình "tại sao trình biên dịch ngu ngốc không thể ( thông dịch viên, bất cứ điều gì) tìm ra điều này? " Đó là những gì đóng cửa là, trình biên dịch ngu ngốc đủ thông minh để con số nó ra.


Hôm qua tôi lần đầu tiên nhận ra cách sử dụng các bao đóng một cách có ý nghĩa - chúng có thể làm cho việc phân tách các mối quan tâm trở nên nhẹ nhàng hơn nhiều: một thành phần sẽ gửi một hàm ẩn danh cho một hàm khác, cơ quan này tạo ra một tham chiếu đến một trường mà thành phần thứ hai không biết. Cảm ơn bạn dựa trên trình biên dịch!
vemv

@vemv - Điều mà bạn có thể làm mà không cần đóng bằng cách tạo một đối tượng chứa tham chiếu đến trường mà thành phần thứ hai không biết và chuyển nó sang thành phần thứ hai, nhưng đó là một nỗi đau rất lớn so với việc đóng mà bạn có thể quyết định không làm điều đó
psr

2

Đóng cửa là tuyệt vời cho logic không đồng bộ.

Nó chủ yếu là về tổ chức mã cho tôi. Có một loạt các hàm cục bộ để phân chia những gì mã đang làm là tốt.

create: function _create(post, cb) {
    // cache the object reference
    var that = this;

    function handleAll(err, data) {
        var rows = data.rows;

        var id = rows.reduce(function(memo, item) {
            var id = +item.id.split(":")[1];
            return id > memo ? id : memo;
        }, 0);
        id++;


        var obj = {
            title: post.title,
            content: post.content,
            id: id,
            // refer to the object through the closure
            _id: that.prefix + id,
            datetime: Date.now(),
            type: "post"
        }

        PostModel.insert(obj, handleInsert);
    }

    // this function doesn't use the closure at all.
    function handleInsert(err, post) {
        PostModel.get(post.id, handleGet);
    }

    // this function references cb and that from the closure
    function handleGet(err, post) {
        cb(null, that.make(post));
    }

    PostModel.all(handleAll);
}

Đây là một ví dụ khác về việc đóng cửa

var cachedRead = (function() {
    // bind cache variable to the readFile function
    var cache = {};

    function readFile(name, cb) {
        // reference cache
        var file = cache[name];
        if (file) {
            return cb(null, file);
        }

        fs.readFile(name, function(err, file) {
            if (file) cache[name] = file;
            cb.apply(this, arguments);
        });
    }

    return readFile;
})();

Và một ví dụ khác

create: function _create(uri, cb, sync) {
    // close over count
    var count = 3;

    // next only fires cb if called three times
    function next() {
        count--;
        // close over cb
        count === 0 && cb(null);
    }

    // close over cb and next
    function errorHandler(err, func) {
        err ? cb(err) : next();
    }

    // close over cb and next
    function swallowFileDoesNotExist(err, func) {
        if (err && err.message.indexOf("No such file") === -1) {
            return cb(err);
        }
        next();
    }

    this.createJavaScript(uri, swallowFileDoesNotExist, sync)

    this.createDocumentFragment(uri, errorHandler, sync);

    this.createCSS(uri, swallowFileDoesNotExist, sync);
},

Thay thế cho việc sử dụng bao đóng là biến cà ri thành các hàm sử dụng f.bind(null, curriedVariable).

Nói chung, logic lập trình không đồng bộ sử dụng các cuộc gọi lại và trạng thái thao tác trong các cuộc gọi lại hoặc phụ thuộc vào việc đóng gói hoặc đóng cửa. cá nhân tôi thích đóng cửa.

Đối với việc sử dụng thừa kế nguyên mẫu, nó cho phép OO? Liệu thừa kế nguyên mẫu có thực sự cần phải làm nhiều hơn thế để nó được coi là "hữu ích". Đó là một công cụ thừa kế, nó cho phép thừa kế, đủ hữu ích.

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.