2012-01-29 42 views
6

Trong mã bên dưới, tôi có thể sử dụng bản in thay cho console.log và chương trình có thể chạy chính xác. Tuy nhiên tôi muốn sử dụng console.log nhưng tôi nhậnLàm cách nào để chuyển giao console.log làm đối số cho hàm JavaScript của tôi?

trái phép gọi

khi chạy

function forEach(array, action) { 
    for (var i=0; i<array.length; i++) 
     action(array[i]); 
} 

forEach(["blah", "bac"], console.log); 
+0

Nó sẽ hoạt động nếu bạn chỉ chuyển 'bàn điều khiển' và gọi' nhật ký' bên trong chức năng forEach. –

Trả lời

7

Nói chung, bạn không thể chuyển trực tiếp phương thức đến các cuộc gọi lại trong Javascript. Các this là ràng buộc tại thời điểm cuộc gọi chức năng, tùy thuộc vào những gì hình thức bạn gọi nó và không có tự động ràng buộc của phương pháp (như có, ví dụ, Python)

//does not work. 
var obj = { 
    x: 17, 
    f: function(){ return this.x; } 
}; 

//inside doSomething, f forgets its "this" should be obj 
doSomething(obj.f) 

Trong những trường hợp này, người ta có thể sử dụng Function.prototype.bind (hoặc một chức năng tương tự từ thư viện của bạn lựa chọn, vì bind là không có mặt trong IE < = 8)

//works (for normal methods - see next bit for console.log in particular) 
var obj = { 
    x: 17, 
    f: function(){ return this.x; } 
}; 

doSomething(obj.f.bind(obj)) 

Thật không may, tuy nhiên, điều này không phải lúc nào đủ cho console.log. Vì nó không phải là một chức năng thực tế trong IE, (nó là một đối tượng host độc ác), bạn không thể sử dụng bind, apply và gọi phương thức trên nó trên trình duyệt đó để giải pháp duy nhất đang rơi trở lại gói gọi trong một hàm ẩn danh

doSomething(function(x){ 
    return console.log(x); 
}); 

Vì gói bảng điều khiển.đăng nhập vào một chức năng ẩn danh dài và gây phiền nhiễu đối với loại Tôi thường thêm chức năng toàn cục sau khi tôi đang phát triển và gỡ lỗi:

function log(message){ return function(x){ 
    return console.log(message, x); 
};}; 

forEach(['asd', 'zxc'], log('->')); 
4

Từ đây: Create shortcut to console.log() in Chrome

Bạn có thể thay console.log với console.log.bind(console)

Giải thích nhờ @ Julian-d:

console.log sẽ giới thiệu trong nội bộ để this và hy vọng nó là console. Nếu bạn 'tách' phương thức log, ví dụ: như var log = console.log, liên kết này bị mất và điều này sẽ không còn trỏ đến console (trong trường hợp này là window thay thế - nếu bạn đang ở trong trình duyệt). Đây là mục đích của .bind(obj): nó trả về một phương thức trong đó nội bộ this được giữ cố định ở obj.

+0

nhưng tại sao bạn không thể thực hiện 'log = console.log'? – meze

+2

@meze: vì 'console.log' sẽ tham chiếu nội bộ thành' this' và hy vọng nó là 'console'. Nếu bạn 'tách' phương thức 'log', ví dụ: giống như 'var log = console.log', liên kết này bị mất và' this' sẽ không còn trỏ đến 'console' (trong trường hợp này là' window' thay thế - nếu bạn đang ở trong trình duyệt). Đây là mục đích của '.bind (obj)': nó trả về một phương thức trong đó 'this' vẫn cố định thành' obj'. –

+0

Hãy nhớ rằng 'bind' không có sẵn trong tất cả các trình duyệt. Xem câu trả lời từ @frm cho một giải pháp không yêu cầu 'bind'. –

3

Bạn có thể giải quyết vấn đề sử dụng một chức năng ẩn danh hoạt động như một cầu nối giữa forEach()console.log()

forEach(["blah", "bac"], function (element) { 
    console.log(element); 
}); 

forEach() của bạn vẫn thuyết bất khả tri về xử lý và bạn không cần phải sắp xếp với bind() để vượt qua một tham khảo làm việc đến console.log().

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