#javascript #node.js #coffeescript
#javascript #node.js #coffeescript
Вопрос:
foo.coffee:
class Foo
constructor: ->
console.log BAR
module.exports = Foo
главное.кофе:
BAR = 1
class Bar
constructor: ->
console.log BAR
new Bar()
Foo = require './foo'
new Foo()
затем
$ coffee main.coffee
1
ReferenceError: BAR is not defined
Почему BAR
он недоступен внутри экземпляра Foo
?
Могу ли я сделать его «видимым» для Foo
объектов (помимо явной передачи его конструктору)?
Ответ №1:
Я думаю, проблема в том, что в CoffeeScript, когда вы объявляете переменную, она всегда компилируется в локальную переменную.
Поэтому в вашем объявлении выше, когда вы это делаете BAR=1
, компилируется в var BAR=1
. Таким образом, переменная всегда ограничена локально, и это означает, что она недоступна для других модулей.
Итак, решение, которое дал вам Джед Шнайдер, является правильным, с одной оговоркой, в Node.js , когда вы находитесь в модуле, this
ссылка указывает на module.exports
объект, а не на global
объект, как, казалось, предполагал Джед (это источник путаницы между node.js и браузер, поскольку вбраузер ведет себя так, как объяснил Джед).
Итак, это всегда верно
//module.js
console.log(this==module.exports) //yield true
В то время как внутри функции this
ключевое слово будет указывать на глобальный объект. Итак, это тоже верно:
//module.js
(function(){
console.log(this==global); //yields true
})()
В этом случае, чтобы решить вашу проблему, вы можете использовать подход Джеда Шнайдера, но обязательно оберните свой код внутри IIFE, чтобы this
он указывал на global
, а не на module.exports
.
Итак, это дает ожидаемые результаты:
do ->
@BAR = 1
class Bar
constructor: ->
console.log BAR
new Bar()
Foo = require './foo'
new Foo()
Это приводит к выводу
1
1
Комментарии:
1. отличное объяснение. Я не знал, что я на самом деле привязан к
module.exports
объекту в node (за вычетом моей специальности), но это явно имеет смысл. 1 за исправление.
Ответ №2:
class Bar
constructor: ->
console.log @BAR
а затем настройка
@BAR = 1
должен делать то, что вы ожидаете. это сокращение для this.
which поместит его в глобальный объект, поскольку вы ожидаете, что будут определены константы. лично я бы создал пространство имен constants и экспортировал его так же, как и вы Foo
.
Комментарии:
1. Проблема не в классе Bar, а в Foo . И если я напишу @BAR = 1 в main.coffee и @BAR в foo.coffee, он печатает «неопределенный».