Java / Coffeescript中关于this / @的困惑
||
我正在研究Trevor Burnham的CoffeeScript书,并且遇到了关于
this
/@
的怪异难题。这个难题有几个部分(我可能会很困惑),所以我将尽力使这一点变得清楚。
我遇到的主要问题是,通过不同的REPL和解释器运行相同的代码,会得到各种各样且不一致的结果。我正在使用(1)coffee
REPL和解释器,(2)Node \的REPL和解释器以及(3)v8的REPL和解释器进行测试。
这是代码,首先是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
和ѭ6global在全球范围内应该是同一件事。但是我非常愿意相信我不理解Javascript中的this
。)
编辑:如果我在调用setName
之前添加this.name = null
/@name = null
(如Pointy在下面建议),那么Coffeescript和Node给我\'Lulu \'和\'null \'回来,但v8仍然为两者返回\'Lulu \'。 (v8在这里对我来说仍然更有意义。我最初在全局上下文中将name
设置为null
,但是后来setName
将其(在全局上下文中)设置为''Lulu \'。因此,此后,我应该在这里看到。 )
没有找到相关结果
已邀请:
3 个回复
粳饶瓢部
当您在Node模块中运行该代码时,您会发现这两个语句的计算结果均为18。这就是为什么ѭ5和ѭ20会得出不同的结果的原因:ѭ5本身将始终指向ѭ22,除非它在ѭ23声明的范围之内。但是在
上下文中调用的函数中,
只会指向
(默认值)。在Node.js模块的任何函数之外,它将指向
。
岭取
值,而与定义它的外部函数中的
值无关。因此,通过调用\“。call()\”设置
的事实对内部\“ setName()\”函数内部的
值没有任何影响,因为调用\“ setName()\”时没有接收者参与。
傻零凰死授
实际上(或应该发生)的是这种情况(假设全局浏览器为
的浏览器):
那么,为什么引擎之间不匹配呢? 因为不同的环境使用不同的方式将全局对象交给您并处理范围。很难确定地说,每种环境都有其行为的单独原因。这在很大程度上取决于他们如何评估代码(这是假设所有引擎都没有错误)。