【问题标题】:Object literal multiple assignment in CoffeeScriptCoffeeScript 中的对象字面量多重赋值
【发布时间】:2015-08-25 02:04:28
【问题描述】:

我是 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,数据不是按分配发生的顺序。

【问题讨论】:

  • 哈哈我一直在尝试为此类对象找到正确的术语。来自 Ruby 背景,我倾向于称它们为哈希,这是不正确的。谢谢(你的)信息。 @FelixKling
  • 它们在 JavaScript 中被称为“对象”。如果你称他们为“哈希”,人们就会明白你的意思(并且可能不会抱怨太多)。
  • 我会抱怨的。 ;-) 对于 OP,有些人所谓的“JSON 对象”是 Object initialiser,也称为 object literal。 JSON 使用这种语法作为其符号,因此会造成混淆。

标签: javascript json node.js coffeescript


【解决方案1】:

这被称为Destructuring Assignment

为了更方便地从复杂数组和对象中提取值,CoffeeScript 实现了 ECMAScript Harmony 提出的 destructuring assignment 语法。当您将数组或对象字面量分配给一个值时,CoffeeScript 会分解并匹配双方,将右侧的值分配给左侧的变量。

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 Objects,就像JSON.parse(content) 的结果一样,并没有作为排序数据结构强制执行。如果您需要确保值的顺序,则必须改用 Array

【讨论】:

  • 太棒了,正是我想要的。非常感谢!
猜你喜欢
  • 2012-11-16
  • 2010-09-07
  • 2011-03-21
  • 2017-07-05
  • 2014-10-11
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
相关资源
最近更新 更多