2012-05-09 19 views
16

Tôi nhận được đầu của tôi quấn về cà ri và các kỹ thuật khác sử dụng Function.prototype.bind.
Có vẻ như rất hữu ích khi thay đổi phạm vi chức năng (ví dụ: this giá trị) trong một số trường hợp nhất định.Tôi có thể nhận được hàm không liên kết từ một hàm bị ràng buộc trong JavaScript không?

Tuy nhiên it looks like you can't change the scope with bind một khi bạn đã làm như vậy:

function f = obj.method.bind(42); 
function g = obj.method.bind('Hi'); 

function f2 = f.bind('Hi'); // “this” is still 42 

Có thể lấy lại chức năng không ràng buộc ban đầu từ một hàm ràng buộc ở tất cả?

+4

bạn đã thử chưa? –

+0

@Martin: Tôi đang tạo ra một fiddle ngay bây giờ. Nó có vẻ như là một câu hỏi rất đơn giản cho một người biết câu trả lời, vì thế tại sao tôi đăng một câu hỏi mà không cần nghiên cứu trước. –

+0

@Martin: Tôi chỉ [kiểm tra các giả định của tôi] (http://jsfiddle.net/dXq2E/) và có vẻ như tôi không thể thay đổi phạm vi bằng 'bind' hai lần. Vì vậy, nó có thể ở tất cả? Có một loại 'unbind' không? –

Trả lời

15

gì phương pháp bind cơ bản nào là một cái gì đó tương tự (không chính xác, bởi vì đối số được thái lát để loại trừ các ngữ cảnh):

function bind(context) { 
    var self = this; 
    return function() { 
     self.apply(context, arguments); 
    } 
} 

Vì vậy, về cơ bản nó trở về một chức năng mà sẽ gọi riêng của mình với bối cảnh nhất định và lập luận . Nếu bạn sau đó bind nó một lần nữa, bạn sẽ được ràng buộc chức năng mới được tạo này, mà sẽ được như bind được triển khai như:

function bind(context) { 
    var self = this; 
    return function() { 
     self.apply(context, arguments); 
    }.bind(otherContext); 
} 

Nhưng vì các chức năng bên trong được trả về bởi hành vi ràng buộc như một đóng cửa nơi bối cảnh gốc là một trong những ràng buộc đầu tiên (self), đó sẽ là bối cảnh trong với chức năng của bạn sẽ được thực sự thực hiện.

22

Tôi nghĩ sẽ hữu ích khi minh họa Win32's answer bằng hình ảnh.

Trình bao bọc được tạo bởi bind đảm bảo chức năng của bạn được gọi với ngữ cảnh cụ thể cho dù là gì.
Trình bao bọc như vậy sẽ luôn bỏ qua ngữ cảnh riêng của nó.

Cho một chuỗi trình bao bọc, bất kỳ ngữ cảnh nào nhưng trong cùng bị mất.
Vì vậy, không có cách nào để thay đổi bối cảnh khi nó đã được thiết lập bằng cách sử dụng bind.

Chained bind calls

+0

Giải thích trực quan tuyệt vời :) – Win32

+0

giải thích thú vị @Dan Abramov !! –