2011-10-19 32 views
13

Tôi đã có một ứng dụng JavaScript sử dụng nhiều cuộc gọi lại. Một chức năng điển hình sẽ gọi lại và bọc lại bằng một cuộc gọi lại khác.Khi nào tôi nên sử dụng cuộc gọi() vs gọi hàm trực tiếp?

Namespace.foo = function(arg, their_on_success) { 
    var my_on_success = function(result) { 
     console.log('my_on_success() called'); 
     if('function' === typeof their_on_success) { 
       their_on_success(result); 
     } 
    } 
    something(arg, my_on_success); 
}; 

Với ví dụ trên, khi cần như một thiết lập cho chúng ta nguồn gốc call() phương pháp (đi qua các var result như là đối số thứ hai) chứ không phải là cách gọi their_on_success() và đi qua trong kết quả thông qua chức năng gọi?

Trả lời

19

call() được sử dụng để thay đổi giá trị này của hàm:

var obj = {a: 0}; 
method.call(obj, "parameter"); 
function method(para) { 
    this.a == 0; // true <-- obj is now this 
} 
7

Lý do duy nhất để sử dụng call (hoặc apply) là nếu bạn muốn thiết lập giá trị của this bên trong hàm .

Vâng, tôi đoán apply có thể hữu ích trong các trường hợp khác vì nó chấp nhận một mảng tham số.

+1

Trường hợp chính cho 'áp dụng' là khi xử lý các đối số biến, do đó bạn có thể chuyển' đối số' cho nó. –

3

Sử dụng phương pháp của một chức năng call() cho phép bạn thay đổi các đối tượng đó là ràng buộc để các chức năng như this trong việc thực hiện các chức năng - điều này cũng được gọi là bối cảnh

their_on_success.call(myContext, results) 

Nhưng, nếu hàm callback của bạn không phụ thuộc vào this, nó không tạo sự khác biệt theo cách bạn gọi.

3

Ví dụ điển hình là khi triển khai hàm cần gọi lại. Khi viết mã OO, bạn muốn cho phép người gọi xác định ngữ cảnh mà một cuộc gọi lại sẽ được gọi.

function validateFormAjax(form, callback, context) { 
    // Using jQuery for simplicity 
    $.ajax({ 
    url: '/validateForm.php', 
    data: getFormData(form), 
    success: function(data) { 
     callback.call(context, data); 
    } 
    }); 
} 

Lưu ý rằng ví dụ của tôi chỉ có thể được thực hiện bằng cách truyền tham số ngữ cảnh để các $.ajax cuộc gọi, nhưng điều đó sẽ không hiển thị cho bạn nhiều về việc sử dụng call

1

Một trường hợp khác cho việc sử dụng cuộc gọi() là khi bạn đang ở trong một môi trường mà bạn không thể tin tưởng vào phương thức riêng của đối tượng đã không được thay thế hoặc bạn biết nó không thực sự có phương thức mà bạn muốn chạy trên nó. hasOwnProperty thường là một phương thức như vậy - có nhiều nơi mà các đối tượng javascript có thể không có phương thức hasOwnProperty riêng của chúng để gọi nó là hasOwnProperty.call (obj, propertyName) là thận trọng.

+1

Tôi nhận được những gì bạn đang nói nhưng tôi nghĩ rằng nó có thể được cải thiện. Một cái gì đó như: JavaScript cho phép bạn chỉ định không có nguyên mẫu nào cả ('Object.create (null)'), ghi đè lên các thuộc tính trên các nguyên mẫu của các đối tượng gốc, hoặc thậm chí trên chính đối tượng đó. Vì vậy, để an toàn, người ta nên sử dụng 'Object.prototype.hasOwnProperty.call (obj, 'someProp')' cho mã của bạn để được bằng chứng đạn. –

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