Flubbing around the revealing module pattern with ES6 syntax, the state of default variables seems dependent on including the trailing () (invocation) on the function.
But, wondering about accessing those underscore variables in the body of the function, some trippy stuff seemed to go on in several different variations.
Investigating some more through several half-baked, half-remembered iterations of the RM pattern; whether it had to fully be an IIFE, or could just stand alone started it off, but then it morphed into looking at how _x, _y, and _z might be accessible.
The error goes away when the trailing () is added, but the behaviour of _._x, accepting a value, that remains. Should it?
Under all this, can default values be added to the pattern using a variation of the ES6 syntax?
const _ = function (_x = 'fish', _y = 'chicken', _z = 'beef') {
// console.log(_x)
_x
_y
_z
return {
// _x,
// _y,
// _z,
get x() { return this._x },
set x(value) { this._x = value }
}
}() // if you invoke it isn't broken per se., but what is the state of revealing module vars?
// _()
let x
_._x = 'fish-ly' // strongly discouraged, but why does it sort of work?
console.log(x)
x = 'tartwell'
console.log(x)
console.log(_._x) // supposed to be private?
console.log(_._x)
x = 'o.m.g'
console.log(x)
console.log(_._x) // gives fishly
console.log(_.x) // no change but gives undefined
console.log(_.x) // no change but gives undefined
_.x[_._x] // TypeError: Cannot read property 'fishly' of undefined
console.log('x', _.x) // with call () trailing function reinstated log shows x was assigned in the statement above
// _.x = 'leafy greens'
console.log(_.x)
Remaining Question: When
_.x[_._x]fires do we get a value for_.x? From the discussion below, the object appears to have taken on a property. But this syntax is not a complete assignment, and if it were it would be a value from the right side. What's happening here?
You've defined
_as a function. Functions, being objects, can have arbitrary key-value pairs assigned to them (unfortunately). Sowill assign a property to the
_xproperty of the single function object (viewable by anything that wishes to reference_._x). The closure-scoped variables (not the properties)_x,_y,_zare still properly encapsulated (they'll only be changeable and viewable by what your_function deliberately exposes), but they won't be created until the_function gets called.In your snippet, you've never invoked
_, so for a clearer understanding of what's going on with the exact same results, you may as well replace_with an empty object named{}:Once you invoke the function, the closure variables which will have just been created will be protected, as desired.
Standalone expressions that don't appear to do anything are permitted. For example:
The last 3 lines don't do anything useful, but the interpreter does parse them as expressions (before discarding them, because nothing is being done with them). Similarly, with the standalone line
the interpreter attempts to parse this as an expression. If it can be evaluated as an expression (and said parsing doesn't throw an error), then the statement on that line will be considered to be complete and valid (despite being useless), and the interpreter will move on to the next line.
But evaluating
_.x[_._x]as an expression fails, because it is equivalent to:And trying to access any property of
undefinedwill throw:As you can see, the error message is identical to the one in your snippet.