Я работаю над книгой Тревора Бернхэма CoffeeScript и у меня столкнетесь со странной загадкой, касающейся этого
/ @
. Головоломка состоит из нескольких частей (и я могу быть очень сбит с толку), поэтому я постараюсь прояснить это как можно яснее.
Основная проблема, с которой я сталкиваюсь, заключается в том, что я получаю разные и непоследовательные результаты выполнения один и тот же код через разные REPL и интерпретаторы. Я тестирую (1) coffee
REPL и интерпретатор, (2) узел REPL и интерпретатор и (3) REPL и интерпретатор v8.
Вот код, сначала как Coffeescript, затем как Javascript:
// coffeescript
setName = (name) -> @name = name
setName 'Lulu'
console.log name
console.log @name
// Javascript via the coffee compiler
(function() {
var setName;
setName = function(name) {
return this.name = name;
};
setName('Lulu');
// console.log for node below - print for v8
// uncomment one or the other depending on what you're trying
// console.log(name);
// console.log(this.name);
// print(name);
// print(this.name);
}).call(this);
Вот результаты:
$ coffee setName.coffee
Lulu
undefined
# coffee REPL
# This appears to be a bug in the REPL
# See https://github.com/jashkenas/coffee-script/issues/1444
coffee> setName = (name) -> @name = name
[Function]
coffee> setName 'Lulu'
'Lulu'
coffee> console.log name
ReferenceError: name is not defined
at repl:2:1
at Object.eval (/Users/telemachus/local/node-v0.4.8/lib/node_modules/coffee-script/lib/coffee-script.js:89:15)
at Interface.<anonymous> (/Users/telemachus/local/node-v0.4.8/lib/node_modules/coffee-script/lib/repl.js:39:28)
at Interface.emit (events.js:64:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream.<anonymous> (readline.js:73:12)
at ReadStream.emit (events.js:81:20)
at ReadStream._emitKey (tty_posix.js:307:10)
coffee> console.log @name
undefined
$ v8 setName.js
Lulu
Lulu
# v8 REPL
>> (function(){var setName; setName=function(name){return this.name=name;};setName('Lulu');print(name);print(this.name);}).call(this);
Lulu
Lulu
# Switch print to console.log or require puts from sys
$ node setName.js
Lulu
undefined
# node REPL
> (function() {
... var setName;
... setName = function(name) {
... return this.name = name;
... };
... setName('Lulu');
... console.log(name);
... console.log(this.name);
... }).call(this);
Lulu
Lulu
Итак, настоящие вопросы, я полагаю, следующие: (1) каких результатов мне следует ожидать и (2) почему эти интерпретаторы и REPL не могут ужиться? (Моя теория гласит, что v8 верна: в глобальном контексте name
и this.name
должны быть одним и тем же, я бы подумал. Но я очень готов поверить что я не понимаю this
в Javascript.)
Изменить : если я добавлю this.name = null
/ @name = null
перед вызовом setName
(как предлагает Пойнти ниже), то Coffeescript и Node возвращают мне «Lulu» и «null», но v8 по-прежнему возвращает «Lulu» для обоих. (v8 по-прежнему имеет для меня больше смысла. Я установил name
в null
сначала в глобальном контексте, но затем setName
устанавливает его (в глобальном контексте) в «Лулу». Так что после этого я должен там увидеть.)