2015-12-18 16 views
5

Nhờ this question Tôi hiểu cách một hàm có thể mất hai bộ ngoặc đơn và cách hàm có thể trả về một hàm khác sẽ kích hoạt ngay lập tức sau khi được trả về.Trong trường hợp nào bạn sẽ sử dụng một hàm trả về một hàm (Javascript) khác?

Điều tôi không hiểu là tại sao điều này là tốt để biết? Làm thế nào điều này có thể được áp dụng để giải quyết một vấn đề?

Các ví dụ về:

function add(x){  
    return function(y){ 
    return x + y; 
    }; 
} 

add(3)(4) === 7; // true 

trình tốt - chắc chắn. Nhưng tại sao không chỉ viết nó như thế này?

function add(a, b) { 
    return a + b; 
} 

add(3, 4) === 7; // true 
+2

chức năng kiểm soát khi mã chạy, không chỉ là gì và ở đâu. điều này thuận tiện cho các cuộc gọi lại, quyền riêng tư và ghi nhớ cũng như các ứng dụng một phần. các ví dụ đơn giản sẽ không làm cho nhu cầu/năng lượng rất rõ ràng, nhưng hãy nhớ mô hình khi bạn cố gắng viết mã mà không sử dụng bất kỳ biến toàn cầu nào. cũng đọc về chức năng tinh khiết và lợi thế của họ để perf/testing/debug/etc – dandavis

+0

bạn có thể thấy câu trả lời của tôi có thể là bạn có thể hiểu những gì bạn đang cố gắng để đạt được. –

+1

'[1, 2, 3, 4, 5] .map (thêm (-1))' chỉ hoạt động trên phiên bản đầu tiên. bạn cũng có thể thực hiện tương tự bằng cách sử dụng 'add.bind (null, -1)' vào ngày 2, nhưng nó có xu hướng chạy chậm hơn so với sử dụng đóng và một hàm mới. – dandavis

Trả lời

0

Nếu bạn biết thông số đầu tiên sẽ luôn giống nhau, thì sẽ thuận tiện khi đóng, thay vì chuyển nó lặp đi lặp lại. Đối với các chương trình đơn giản, nó có thể không có ý nghĩa. Tuy nhiên, đối với các chương trình xử lý các thông số lặp đi lặp lại thường xuyên hơn, kỹ thuật này chắc chắn có ích.

2

Cho phép lấy cùng mã mà bạn đã đề cập.

function add(x) {  
     return function(y) { 
     return x + y; 
     }; 
    } 

    var adder3 = add(3); //Forming adder3 
    var op1 = adder3(4) // 7 
    var op1 = adder3(5) // 9 

    // Now adder 10: 
    var adder10 = add(10); //Forming adder3 
    var op1 = adder3(4) // 14 
    var op1 = adder3(5) // 15; 

Hy vọng bạn hiểu !!

Hoàn nguyên cho tôi nếu bạn cần thêm thông tin về việc đóng cửa.

0

không có điểm để sử dụng ngay lập tức. bạn sẽ sử dụng nó để tạo một hàm để đính kèm nó vào một sự kiện hoặc sử dụng như một hàm gọi lại cho một hàm không đồng bộ. một ví dụ có thể là:

function factory(param){ 
    return function(result) { 
     if (result==param) dosomething(); 
    } 
} 

$('#domobject').click({ 
    param = $('#domvalue').value; 
    asynch_function(factory(param)); 
}); 

Ở đây tôi đã đính kèm một sự kiện nhấp chuột vào có lẽ là một nút. Khi nó được nhấp vào nó sẽ lấy giá trị của một đầu vào và tạo ra một hàm dựa trên nó và gọi một hàm không đồng bộ với hàm mới được tạo ra như hàm gọi lại của nó. Hàm không đồng bộ có thể là một yêu cầu ajax. Khi hàm không đồng bộ hoàn thành chức năng mà nhà máy đã tạo, gọi lại, sẽ được gọi. Nó sẽ kiểm tra giá trị trả về hàm không đồng bộ được chuyển đến cuộc gọi lại với tham số được chỉ định khi sự kiện được đính kèm.

Nếu chúng tôi di chuyển tra cứu bên trong hàm gọi lại, thì chúng tôi sẽ không cần nhà máy hoặc thông số, nhưng sau đó nó sẽ sử dụng giá trị trong đầu vào tại thời điểm hàm asynch trả về, thay vì khi nút được nhấp vào sau đó và giá trị có thể đã thay đổi.

Đôi khi, bạn sẽ không thể có được giá trị bạn cần trong ngữ cảnh gọi lại vì các lý do khác. Hoặc nó có thể chỉ là bạn muốn trừu tượng ra một lớp chức năng, do đó bạn không phải gõ lại một phiên bản hơi khác của nó trong tất cả các nơi bạn sử dụng nó.

1

dụ bạn gọi là đóng cửa

  • Nội quy và Side Effects đóng cửa

  1. đóng cửa có thể truy cập để biến các chức năng bên ngoài của ngay cả một fter chức năng bên ngoài trả về:

Một trong những tính năng quan trọng nhất và tế nhị với đóng cửa là các chức năng bên trong vẫn có quyền truy cập vào các biến chức năng bên ngoài của ngay cả sau khi các chức năng bên ngoài đã trở lại. Đúng, bạn đọc chính xác. Khi các hàm trong JavaScript thực hiện, chúng sử dụng cùng một chuỗi phạm vi có hiệu lực khi chúng được tạo. Điều này có nghĩa là ngay cả sau khi hàm ngoài đã trả về, hàm bên trong vẫn có quyền truy cập vào các biến của hàm bên ngoài. Do đó, bạn có thể gọi hàm bên trong sau trong chương trình của bạn. Ví dụ này cho thấy:

function celebrityName(firstName) { 
    var nameIntro = "This celebrity is "; 
    // this inner function has access to the outer function's variables, including the parameter​ 
    function lastName(theLastName) { 
     return nameIntro + firstName + " " + theLastName; 
    } 
    return lastName; 
}​​ 
var mjName = celebrityName("Michael"); // At this juncture, the celebrityName outer function has returned.​ 
​​ // The closure (lastName) is called here after the outer function has returned above​ 
​ // Yet, the closure still has access to the outer function's variables and parameter​ 
mjName("Jackson"); // This celebrity is Michael Jackson 

 

  1. đóng cửa cửa hàng tham chiếu đến biến các chức năng bên ngoài của; chúng không lưu trữ giá trị thực tế. Các đóng cửa trở nên thú vị hơn khi giá trị của biến của hàm bên ngoài thay đổi trước khi đóng được gọi. Và tính năng mạnh mẽ này có thể được khai thác một cách sáng tạo, chẳng hạn như biến ví dụ này tư nhân đầu tiên được chứng minh bởi Douglas Crockford:

function celebrityID() { 
    var celebrityID = 999; 
    // We are returning an object with some inner functions​ 
    // All the inner functions have access to the outer function's variables​ 
    return { 
     getID: function() { 
      // This inner function will return the UPDATED celebrityID variable​ 
      // It will return the current value of celebrityID, even after the changeTheID function changes it​ 
      return celebrityID; 
     }, 
     setID: function(theNewID) { 
      // This inner function will change the outer function's variable anytime​ 
      celebrityID = theNewID; 
     } 
    }​ 
}​​ 
var mjID = celebrityID(); // At this juncture, the celebrityID outer function has returned.​ 
mjID.getID(); // 999​ 
mjID.setID(567); // Changes the outer function's variable​ 
mjID.getID(); // 567: It returns the updated celebrityId variable 

trang web tham khảo: http://javascriptissexy.com/understand-javascript-closures-with-ease/

0

Ngoài việc đóng cửa, bạn cũng có thể sử dụng nó để xử lý trước như một công việc một lần, hãy cân nhắc xem bạn có phải làm gì đó chuyên sâu hay không, ví dụ: tạo ra hàng triệu thứ;

function generateSessionSecrets(lock) { 
    var secrets = [], i = 1000000; 
    while (i-- > 0) { 
     secrets[i] = Math.random(); 
    } 
    return function(key, i) { 
     if (key === lock) return secrets[i]; 
    } 
} 

var chest = generateSessionSecrets('fizz'); 
chest('fizz', 0); // e.g. 0.2096199430525303 
chest('fizz', 1); // e.g. 0.30329699837602675 
// ... 
chest('fizz', 0); // still 0.2096199430525303 

(Đây là một ví dụ về khái niệm, không phải là một ví dụ về an ninh thực)

1

Chức năng mà trở lại chức năng này rất hữu ích khi bạn muốn chức năng tương tự mà phụ thuộc vào một số thông số.

Một ví dụ thực tế đời sống: [].sort có thể được gọi với một chức năng so sánh tùy chỉnh, nhưng nó có thể làm cho tinh thần để xác định một hàm comparator để cho phép nhiều tùy chỉnh:

function comparator(options) { // Function which returns a function 
    return function(a, b, tmp) { 
    if(options.reverse) tmp = a, a = b, b = tmp; 
    if(options.map) a = options.map(a), b = options.map(b); 
    if(options.func) return options.func(a, b); 
    return a < b ? -1 : (b < a ? 1 : 0); 
    } 
} 

Sau đó, bạn có thể sử dụng

[1,11,10,2].sort(comparator({map: String}));    // [1, 10, 11, 2] 
[1,11,10,2].sort(comparator({reverse: true}));   // [11, 10, 2, 1] 
[1,11,10,2].sort(comparator({func: Function.prototype})); // [1, 11, 10, 2] 
1

nếu chúng ta yêu cầu hàm ở trạng thái nhất định với giá trị nhất định thì chúng ta có thể sử dụng hàm bên trong hàm khác và trả về hàm đó để hàm trả về với trạng thái nhất định có thể được sử dụng trực tiếp trong kịch bản khác nhau. bạn có thể xem ví dụ khác về đóng. http://javascriptissexy.com/understand-javascript-closures-with-ease/

Các vấn đề liên quan