I'm a bit of a newbie in Javascript. I was looking through a bit of Coffeescript code for an Atom package, and I stumbled upon this piece of code:
loadProperties: ->
@properties = {}
fs.readFile path.resolve(__dirname, '..', 'completions.json'), (error, content) =>
{@pseudoSelectors, @properties, @tags} = JSON.parse(content) unless error?
return
I was a bit confused by the last line {@pseudoSelectors, @properties, @tags} = JSON.parse(content) unless error?
because it seems like it assigns multiple values from the parsed JSON content. In my confusion, I decided to convert this back to Javascript using js2Coffee, and I ended up with the following:
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));
This code is a bit more understandable than the above. I can see that ref is assigned the object parsed from the content stream, and is then used to assign the other variables with their designated data. My question is, how does this type of assignment work? In Coffeescript, how does the preprocessor know where to assign the values, and in what order to assign them in?
By inspecting completions.json, the data is not in the order in which the assignments occur.
This is known as Destructuring Assignment.
CoffeeScript interprets an object or array on the left side of an
=
as a pattern, matching the names used...@pseudoSelectors
@properties
@tags
...to properties or indices within the value being assigned:
JSON.parse(content).pseudoSelectors
JSON.parse(content).properties
JSON.parse(content).tags
(Defining the additional
ref
to avoid reevaluatingJSON.parse(content)
for each.)As for order, CoffeeScript will generally use the order they're mentioned within the assignment. Moving
@pseudoSelectors
to the 3rd property in the pattern will be echoed in the generated JavaScript.Though, JavaScript
Object
s, like the result ofJSON.parse(content)
, aren't enforced as sorted data structures. If you need to ensure the order of the values, you'll have to instead use anArray
.