Я сам искал решение этой проблемы (вот как я нашел ваш вопрос).
Как отметил Тим, браузеры webkit (Safari, Chrome) в этом случае полагаются на this
, равное console
. Firefox, однако, нет. Таким образом, в FF вы можете переназначить функцию и сохранить номера строк (в противном случае все журналы выглядят так, как будто они возникли в функции журналирования, что не очень полезно). Лучший способ проверить, какой у вас браузер - это сделать это и проверить результат. Вот как это проверить (в Coffeescript):
# Check to see if reassigning of functions work
f = console.log
assignSupported = true
try
f('Initializing logging...')
catch e
assignSupported = false
Позже, когда вы сделаете функции, проверьте assignSupported и действуйте соответственно:
levels =
ERROR: 1
WARN: 2
LOG: 3
INFO: 4
DEBUG: 6
log.setLevel = (newLevel) ->
for label, level of levels
if level > newLevel # Skip low levels
continue
name = label.toLowerCase()
f = -> # Fallback - empty function. In Js: var f = function () {}
if console?[name]
if assignSupported
f = console[name] # Wee, we'll have line numbers.
else
# Webkit need the this of console.log (namely, console)
# preserved, so we use a wrapper.
#
# Calling console[name] within the returned wrapper
# makes [name] a subject of the closure, meaning
# that it's the last value in the iteration -
# we need to preserve it.
f = ((n) ->
return (-> console[n].apply(console, arguments)))(name)
log[name] = f
log.setLevel levels.DEBUG
Строки:
f = ((n) ->
return (-> console[n].apply(console, arguments)))(name)
может выглядеть немного странно. Это связано с тем, что name
является переменной цикла и имеет лексическую привязку, что означает, что будет использоваться значение во время выполнения, которое всегда будет последним level
. Он компилируется в этот javascript (в случае, если его легче читать):
f = (function(n) {
return (function() {
return console[n].apply(console, arguments);
});
})(name);