Как заставить переменную быть локальной в coffeescript?
С учетом следующего кода:
outer=1
f=->
local=1
outer=0
local+outer
coffeescript создает var
для local
, но re-ueses outer
:
var f, outer;
outer = 1;
f = function() {
var local;
local = 1;
outer = 0;
return local + outer;
};
Это то, чего вы ожидаете.
Однако, если вы используете локальную переменную в функции, она зависит от внешней области, если переменная объявлена локальной или нет. Я знаю, что это функция, но она вызывала некоторые ошибки, потому что я должен проверять все внешние области для переменных с тем же именем (которые объявлены перед моей функцией). Интересно, есть ли способ предотвратить этот тип ошибки, объявив переменные локальными?
Ответы
Ответ 1
Эта ошибка обычно возникает, когда вы не используете соответствующие описательные имена переменных. Тем не менее, существует способ затенять внешнюю переменную, несмотря на то, что в принятом ответе говорится:
outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
Это создает IIFE, с outer
как один аргумент. Аргументы функции теневые внешние переменные, как и ключевое слово var
, так что это будет иметь поведение, которое вы ожидаете. Однако, как я уже сказал, вы должны просто называть свои переменные более описательно.
Ответ 2
Нет, эта функция явно не доступна в CoffeeScript (внимание мое):
Это поведение фактически идентично области Ruby для локальных переменных. Поскольку у вас нет прямого доступа к ключевому слову var
, невозможно назначить внешнюю переменную специально, вы можете ссылаться только на нее. Поэтому будьте осторожны, чтобы случайно не использовать имя внешней переменной, если вы пишете глубоко вложенную функцию.
Ответ 3
Вы можете ввести обычный JavaScript в свой CoffeeScript, используя обратные ссылки:
outer=1
f=->
local=1
`var outer=0`
local+outer
В большинстве случаев я стараюсь избегать этого и предпочитаю переименовывать внешние переменные, указывая их область/контекст в их имени. Однако иногда это полезно, например, при использовании модуля отладки, где я всегда хочу иметь функцию debug()
, доступную для ведения журнала, как в этом примере:
#logging fn for module setup and other global stuff
debug = require("debug")("foo")
class Bar
#local logging fn to allow Bar instances to log stuff
`var debug = require("debug")("foo:bar")`
Если вы хотите сохранить простой JS как минимум, просто объявите переменную, а затем назначьте использование CoffeeScript:
`var debug`; debug = require("debug") "foo:bar"
Пример компилируется в:
// Generated by CoffeeScript 1.7.1 -- removed empty lines for SO answer
var Bar, debug;
debug = require("debug")("foo");
Bar = (function() {
function Bar() {}
var debug;
debug = require("debug")("foo:bar");
return Bar;
})();
Мне нравится этот прямой способ объявления переменных лучше, чем (IMHO) более медленный и менее читаемый взлом IIFE.
Ответ 4
Как отметил Аарон, затенение действительно возможно:
outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
Поскольку внешнее значение не требуется внутри локальной функции, оно может быть инициализировано с помощью null
только в том случае, если в какой-то момент переменная outer
будет удалена из внешней области (что вызовет ошибку).
#outer=1
f=->
do (outer=null) ->
local=1
outer=0
local+outer
Ответ 5
important = 10 # global
main = ->
agentId = '007'
console.log 'global `important`', important # refers to the global variable
((important) -> # place the local variables as the arguments
important = 20
console.log 'local `important`', important # locally scoped
console.log 'parent scope value', agentId # even access variables from the above scopes
)() # not passing anything, so the local varibales would be left undefined at first
console.log 'global `important`', important # the global variable remains untouched
main()