这个/ @在Javascript / Coffeescript的一个谜题 [英] A puzzle about this/@ in Javascript/Coffeescript

查看:124
本文介绍了这个/ @在Javascript / Coffeescript的一个谜题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在浏览Trevor Burnham的 书,我遇到了一个关于这个 / @ 。这个拼图有几个部分(我可能只是很困惑),所以我会尽量使这清楚,我可以。

I'm working through Trevor Burnham's CoffeeScript book and I've run into a weird puzzle concerning this/@. The puzzle has a few parts (and I may be just very confused), so I'll try to make this as clear as I can.

主要问题我'我有通过不同的REPL和解释器运行同一个代码的变化和不一致的结果。我用(1)咖啡 REPL和解释器,(2)Node的REPL和解释器和(3)v8的REPL和解释器测试。

The main problem I'm having is that I get varied and inconsistent results running the same code through different REPLs and interpreters. I'm testing with (1) the coffee REPL and interpreter, (2) Node's REPL and interpreter and (3) v8's REPL and interpreter.

下面是代码,首先是Coffeescript,然后是Javascript:

Here's the code, first as Coffeescript then as 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

所以真正的问题, )我应该得到什么结果和(2)为什么这些解释器和REPL不能一起? (我的理论是v8是正确的:在全局上下文 name this.name 应该是相同的东西,我会想的,但我已经准备好相信我不明白这个在Javascript。)

So the real questions, I suppose, are (1) what results should I expect and (2) why can't these interpreters and REPLs get along? (My going theory is that v8 is right: in the global context name and this.name should be the same thing, I would have thought. But I'm very ready to believe that I don't understand this in Javascript.)

编辑:如果我添加 this.name = null / @name = null 在调用 setName (如Pointy建议如下)之前,Coffeescript和Node给我'Lulu'和'null'回来,但v8仍然返回'Lulu'。 (v8在我这里仍然更有意义,我设置名称 null 最初在全局上下文, code> setName 将它(在全局上下文中)设置为'Lulu'。因此,这是我应该看到的。)

Edit: If I add this.name = null/@name = null before calling setName (as Pointy suggests below) then Coffeescript and Node give me 'Lulu' and 'null' back but v8 still returns 'Lulu' for both. (v8 still makes more sense to me here. I set name to null initially in the global context, but then setName sets it (in the global context) to 'Lulu'. So afterwards, this is what I should see there.)

推荐答案

因此,首先,CoffeeScript REPL存在一个错误,问题1444 ,这是我在Telemachus提请我注意之后的报告。

So, first off, there's a bug with the CoffeeScript REPL, issue 1444, which I reported after Telemachus brought this to my attention.

但是更有趣的问题在这里(我需要注意在我的CoffeeScript书)是在节点的最外层范围内的 this 。 js模块不是全局 -it的模块的 exports 。试试这个:

But the more interesting issue here (and one that I need to note in my CoffeeScript book) is that this in the outermost scope of a Node.js module isn't global—it's that module's exports. Try this out:

console.log this is exports
console.log do -> this is global

你会发现两个语句都求值为 true 在Node模块中运行该代码。这就是为什么 name @name 评估不同的东西: name 本身将始终指向 global.name ,除非它在 var name 声明的范围内;但 @name 只会指向全局中调用的函数中的 global.name / code> context(默认)。在Node.js模块中,在任何函数之外,它将指向 exports.name

You'll find that both statements evaluate to true when you run that code in a Node module. That's why name and @name evaluate to different things: name by itself will always point to global.name, unless it's in the scope of a var name declaration; but @name will only point to global.name in a function called in the global context (the default). In a Node.js module, outside of any function, it'll point to exports.name.

这篇关于这个/ @在Javascript / Coffeescript的一个谜题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆