javascript – 为什么e = 1和e = e 1在CoffeeScript中编译方式不同?

前端之家收集整理的这篇文章主要介绍了javascript – 为什么e = 1和e = e 1在CoffeeScript中编译方式不同?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直认为< var> = 1且< var> =< var> 1在JS中具有相同的语义.
现在,这个CoffeeScript代码在应用于全局变量e时编译为不同的 JavaScript
a: ->
  e = e + 1
b: ->
  e += 1

请注意,b使用全局变量,而a定义局部变量:

({
  a: function() {
    var e;
    return e = e + 1;
  },b: function() {
    return e += 1;
  }
});

Try it yourself.
这是一个错误还是有这样的原因?

解决方法

我想我会称这是一个错误,或者至少是一个无证的边缘情况或歧义.我没有在文档中看到任何明确指定何时在CoffeeScript中创建新局部变量的内容,因此它归结为通常的

We do X when the current implementation does X and that happens because the current implementation does it that way.

那类的东西.

似乎触发创建新变量的条件是赋值:当您尝试为其赋值时,看起来CoffeeScript决定创建新变量.所以这:

a = ->
  e = e + 1

var a;
a = function() {
  var e;
  return e = e + 1;
};

使用本地e变量,因为您明确指定了一个值.如果你只是在表达式中引用e:

b = ->
  e += 1

那么CoffeeScript不会创建一个新变量,因为它不能识别那里有e的赋值. CS识别表达式,但不够聪明,e = 1等同于e = e 1.

有趣的是,当你使用属于CoffeeScript而不是JavaScript的op = form时,CS确实会识别出一个问题.例如:

c = ->
  e ||= 11

产生一个错误

the variable “e” can’t be assigned with ||= because it has not been defined

我认为对e = 1做出类似的抱怨是合情合理的.或者所有op = b表达式都应该扩展为a = a op b并且应该被平等对待.

如果我们查看CoffeeScript源代码,我们可以看到正在发生的事情.如果你捅了一下,你会发现所有的op =构造最终都会经历Assign#compileNode

compileNode: (o) ->
  if isValue = @variable instanceof Value
    return @compilePatternMatch o if @variable.isArray() or @variable.isObject()
    return @compileSplice       o if @variable.isSplice()
    return @compileConditional  o if @context in ['||=','&&=','?=']
  #...

所以对于特定于CoffeeScript的op =条件结构有特殊的处理方式.快速回顾表明,非条件运算的op = b(即除||,&&和?之外的运算)直接传递给JavaScript.那么compileCondtional会发生什么?好吧,正如预期的那样,it checks that you’re not using undeclared variables

compileConditional: (o) ->
  [left,right] = @variable.cacheReference o
  # Disallow conditional assignment of undefined variables.
  if not left.properties.length and left.base instanceof Literal and 
         left.base.value != "this" and not o.scope.check left.base.value
    throw new Error "the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been defined."
  #...

我们看到了错误消息 – > a || = 11和注释,注意到当某个地方没有定义时你不被允许进入|| = b.

猜你在找的JavaScript相关文章