2012-11-08 23 views
23

Có một số chức năng, thats làm việc gì đó lâu dài và cung cấp gọi lại.Làm cách nào để chuyển ngữ cảnh sang chức năng ẩn danh?

someFunc: function(argument, callback, context) { 
    // do something long 

    // call callback function 
    callback(context); 
} 

Trong ứng dụng Tôi sử dụng chức năng này

someFunc('bla-bla', function (context) { 
    // do something with this scope 
    context.anotherFunc(); 
}, this); 

Làm thế nào để thực hiện chức năng gọi lại mà không đi context tham số?

Cần một số như thế này:

someFunc('bla-bla', function() { 
    // do something with this scope 
    this.anotherFunc(); 
}, this); 
+1

Vì vậy, trong ví dụ cuối cùng của bạn có vẻ như bạn đang chuyển ngữ cảnh (đến ít nhất) bạn chỉ tò mò về cách tham chiếu đối số nếu nó không được đặt tên? –

+0

Bạn đang chuyển tham số, bạn không sử dụng nó. Và tôi không hiểu tại sao. – bfavaretto

+2

@bfavaretto: OP đang sử dụng nó bằng cách chuyển nó vào hàm gọi lại để gọi lại có thể tận dụng các phương thức của giá trị 'này' bên ngoài. Vì vậy, câu hỏi là làm thế nào để đạt được khối mã cuối cùng ... nhận được 'điều này' thích hợp trong cuộc gọi lại vì vậy nó không cần phải được chuyển như một đối số. –

Trả lời

37

Câu trả lời được chấp nhận có vẻ hơi lỗi thời. Giả sử bạn đang hoạt động trên một trình duyệt tương đối hiện đại, bạn có thể sử dụng Function.prototype.bind trong vanilla javascript. Ngoài ra, nếu bạn đang sử dụng underscore hoặc jQuery, bạn có thể sử dụng lần lượt _.bind hoặc $.proxy (dự phòng sẽ được hoàn lại thành call/apply nếu cần).

Dưới đây là một minh chứng đơn giản trong ba lựa chọn:

// simple function that takes another function 
// as its parameter and then executes it. 
function execute_param(func) { 
    func(); 
} 

// dummy object. providing an alternative context. 
obj = {}; 
obj.data = 10; 

// no context provided 
// outputs 'Window' 
execute_param(function(){ 
    console.log(this); 
}); 

// context provided by js - Function.prototype.bind 
// src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 
// outputs 'Object { data=10 }'' 
execute_param(function(){ 
    console.log(this); 
}.bind(obj)); 

// context provided by underscore - _.bind 
// src: http://underscorejs.org/#bind 
// outputs 'Object { data=10 }' 
execute_param(_.bind(function(){ 
    console.log(this); 
},obj)); 

// context provided by jQuery - $.proxy 
// src: http://api.jquery.com/jQuery.proxy/ 
// outputs 'Object { data=10 }' 
execute_param($.proxy(function(){ 
    console.log(this); 
},obj)); 

Bạn có thể tìm mã trong một jsfiddle đây: http://jsfiddle.net/yMm6t/1/ (lưu ý: đảm bảo rằng các nhà phát triển giao diện điều khiển đang mở, hoặc bạn sẽ không thấy bất kỳ đầu ra)

+0

Có. Bây giờ tôi đang sử dụng gạch dưới ở khắp mọi nơi :) – acelot

+0

@ PiONeeR Vâng, tôi cũng vậy :) Bạn có thể muốn xem xét lại những gì nên là câu trả lời được chấp nhận. – EleventyOne

+8

Đây phải là câu trả lời được chấp nhận. – Gamak

13

Sử dụng Function.prototype.call để gọi một chức năng và tự thiết lập giá trị this chức năng đó.

someFunc: function(argument, callback, context) { 
    callback.call(context); // call the callback and manually set the 'this' 
} 

Bây giờ gọi lại của bạn có giá trị mong đợi this.

someFunc('bla-bla', function() { 
    // now 'this' is what you'd expect 
    this.anotherFunc(); 
}, this); 

Tất nhiên bạn có thể vượt qua đối số như bình thường trong .call gọi.

callback.call(context, argument); 
Các vấn đề liên quan