2013-02-20 33 views
8

Tôi tin rằng cả hai đều cho phép bạn kiểm soát giá trị của 'điều này', nhưng ngoài ra, tôi có một chút không rõ ràng và Google/SO không giúp ích nhiều cho đến nay. Bất kỳ làm rõ được đánh giá cao. Tôi đã tìm thấy điều này, nhưng tôi không tin rằng nó kể toàn bộ câu chuyện:

"Khi lần đầu tiên tôi được học về phương pháp() ủy nhiệm của jQuery, tôi nghĩ rằng nó là một chút ngớ ngẩn, sau tất cả, Javascript đã có Các phương thức gọi() và áp dụng() để thay đổi ngữ cảnh thực thi Nhưng một khi bạn nhận ra rằng phương thức proxy() của jQuery cho phép bạn ràng buộc() và unbind() sự kiện các trình xử lý bất kể ngữ cảnh, nó trở nên rõ ràng phương pháp này là

+0

Cụm từ tìm kiếm hữu ích cho Google-fu: ngữ cảnh thực thi JavaScript. – cmbuckley

+2

Rất nhiều thứ jQuery hoàn toàn vô nghĩa. Thực tế là nhiều người nghĩ rằng nó tốt để sử dụng '$ (this) .attr ('id')' thay vì 'this.id', ngay lập tức. Tôi đã không nhìn vào '$ .proxy', nhưng nó hoàn toàn có thể là nó chỉ giống nhau: dư thừa và vô nghĩa. –

+0

@Kolink đó là điều khi bạn viết một hàm trả về hàm trả về áp dụng. Hầu hết các thư viện đều có phương pháp này. – epascarello

Trả lời

11

cuộc gọi/áp dụng là một invocation single-shot. $ .proxy tạo một hàm mới vĩnh viễn bị ràng buộc vào một cái gì đó:

fn.call(foo); //call once 

var otherFn = $.proxy(fn, foo); // you can call it again later 

var otherOtherFn = fn.bind(foo); // ES5 standard way 

Là một đơn giản hóa (rất đơn giản), $.proxy đang tạo ra một chức năng mới mà các cuộc gọi call:

$.proxy = function(fn, newThis) { 
    return function() { 
     fn.call(newThis); 
    } 
} 

Nó là tương tự như ES2 của

5

Hãy xem nguồn jQuery:

proxy: function(fn, context) { 
    var tmp, args, proxy; 

    if (typeof context === "string") { 
     tmp = fn[ context ]; 
     context = fn; 
     fn = tmp; 
    } 

    // Quick check to determine if target is callable, in the spec 
    // this throws a TypeError, but we will just return undefined. 
    if (!jQuery.isFunction(fn)) { 
     return undefined; 
    } 

    // Simulated bind 
    args = core_slice.call(arguments, 2); 
    proxy = function() { 
     return fn.apply(context || this, args.concat(core_slice.call(arguments))); 
    }; 

    // Set the guid of unique handler to the same of original handler, so it can be removed 
    proxy.guid = fn.guid = fn.guid || jQuery.guid++; 

    return proxy; 
}, 

Nếu bạn loại bỏ mã bộ nhớ đệm và làm cho nó ngắn hơn một chút, bạn về cơ bản có được .apply() (Tôi nghĩ rằng tôi dịch mã cắt chính xác):

proxy: function(fn, context) { 
    var args = [].slice.call(arguments, 2); 

    return function() { 
     return fn.apply(context || this, args.concat([].slice.call(arguments))); 
    }; 
} 
1

$.proxy bạn có thể gọi vào một chức năng và hàm mà nó trả về sẽ luôn luôn có một ngữ cảnh cụ thể. Điều đó có nghĩa rằng nếu bạn chạy

$.proxy(function() {console.log(this.val)}, {val: 1}).call({val: 2}); 

Nó sẽ đăng nhập 1 vì hàm này luôn luôn ràng buộc với đối tượng mà ban đầu đã được thông qua để proxy

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