Je travaille sur le livre de Trevor Burnham. CoffeeScript et je suis tombé sur une étrange énigme concernant this
/ @
. L'énigme comporte plusieurs parties (et je suis peut-être tout simplement très confus), je vais donc essayer d'être aussi clair que possible.
Le principal problème que j'ai est que j'obtiens des résultats variés et incohérents en cours d'exécution. le même à travers différents REPLs et interpréteurs. Je teste avec (1) le coffee
REPL et interprète, (2) REPL et interprète de Node et (3) REPL et interprète de v8.
Voici le code, d'abord en Coffeescript puis en 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);
Voici les résultats :
$ 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
Les vraies questions, je suppose, sont donc (1) quels résultats dois-je attendre et (2) pourquoi ces interprètes et REPL ne peuvent-ils pas s'entendre ? (Ma théorie actuelle est que v8 a raison : dans le contexte global name
y this.name
devrait être la même chose, j'aurais pensé. Mais je suis tout à fait prêt à croire que je ne comprends pas this
en Javascript).
Editar : Si j'ajoute this.name = null
/ @name = null
avant d'appeler setName
(comme le suggère Pointy ci-dessous) alors Coffeescript et Node me renvoient 'Lulu' et 'null' mais la v8 renvoie toujours 'Lulu' pour les deux. (La v8 est toujours plus logique pour moi ici. J'ai mis name
a null
initialement dans le contexte global, mais ensuite setName
le définit (dans le contexte global) comme "Lulu". Donc après, c'est ce que je devrais voir là).