CoffeeScript 中的对象字面量多重赋值

Object literal multiple assignment in CoffeeScript

我是 Javascript 的新手。我正在查看 Atom 包的一些 Coffeescript 代码,我偶然发现了这段代码:

loadProperties: ->
    @properties = {}
    fs.readFile path.resolve(__dirname, '..', 'completions.json'), (error, content) =>
      {@pseudoSelectors, @properties, @tags} = JSON.parse(content) unless error?
      return

我对最后一行 {@pseudoSelectors, @properties, @tags} = JSON.parse(content) unless error? 有点困惑,因为它似乎从解析的 JSON 内容中分配了多个值。在我的困惑中,我决定使用 js2Coffee 将其转换回 Javascript,结果如下:

function() {
this.properties = {}; // make list of properties (global to provider)
return fs.readFile(path.resolve(__dirname, '..', 'completions.json'), (function(_this) { //load completions.json (using path module)
  return function(error, content) { // edit: nvm, js2coffee's fault. not sure why they wrapped the call back in another anonymous function, but this is a node stream callback
    var ref;
    if (error == null) { // if there are no errors
      ref = JSON.parse(content), _this.pseudoSelectors = ref.pseudoSelectors, _this.properties = ref.properties, _this.tags = ref.tags;
    }
  };
})(this));

这段代码比上面的更容易理解一点。我可以看到 ref 被分配了从内容流中解析的对象,然后用于将其他变量分配给它们指定的数据。我的问题是,这种类型的分配如何工作?在 Coffeescript 中,预处理器如何知道在哪里分配值,以及以什么顺序分配它们?

通过检查 completions.json,数据与赋值发生的顺序不一致。

这被称为 Destructuring Assignment

To make extracting values from complex arrays and objects more convenient, CoffeeScript implements ECMAScript Harmony's proposed destructuring assignment syntax. When you assign an array or object literal to a value, CoffeeScript breaks up and matches both sides against each other, assigning the values on the right to the variables on the left.

CoffeeScript 将 = 左侧的对象或数组解释为模式,匹配使用的名称...

  • @pseudoSelectors
  • @properties
  • @tags

...分配给值内的属性或索引:

  • JSON.parse(content).pseudoSelectors
  • JSON.parse(content).properties
  • JSON.parse(content).tags

(定义额外的 ref 以避免为每个重新计算 JSON.parse(content)。)

至于顺序,CoffeeScript 通常会使用作业中提到的顺序。将模式中的 @pseudoSelectors 移动到第三个 属性 将在生成的 JavaScript.

中回显
{@properties, @tags, @pseudoSelectors} = JSON.parse(content) unless error?
var ref;

if (typeof error === "undefined" || error === null) {
  ref = JSON.parse(content),
    this.properties = ref.properties,
    this.tags = ref.tags,
    this.pseudoSelectors = ref.pseudoSelectors; // now last
}

不过,JavaScript ObjectsJSON.parse(content) 的结果一样,并未强制执行为已排序的数据结构。如果您需要确保值的顺序,则必须改用 Array.