The title speaks for itself.
I want to do something like:
if (!log) {
const log = console.log
}
OR
const log = typeof(log) === 'undefined' ? console.log : ''
I know the first one won't work because I couldn't declare a const in the if block even if log wasn't already declared, but I really wish I could find a way to do this without: 
The second is the right approach, but I suggest:
if (typeof(log) === 'undefined') const log = console.log
But log should be defined as per an update earlier today.
The second is the right approach, but I suggest [ . . . ]
Cool, cool.
logshould be defined as per an update earlier today
Awesome!
I was really just using that one as an example while trying to learn how to handle that situtation. I thought we couldn't declare in an if block, but I was obviously doing something else wrong in my code.
Thanks!
EDIT
This is not it!
See this post for the correct answer.
Got it!
if (typeof(RH) === 'undefined'){ window["RH"] = "Richard Headkid"}
I know the first one won't work because I couldn't declare a
constin theifblock even iflogwasn't already declared
Well, you could. But it's scope would be within the if block; which isn't particularly useful to you. const, like let, is scoped within the innermost enclosing {block}.
The simplest way to do this would simply be to make it a variable.
if (typeof(RH) === 'undefined'){ RH = "Richard Headkid"}
Works fine. It isn't a const, but then neither is your solution.
If you really want it to be a constant, you could do something like:
if (typeof(RH) === 'undefined'){ Object.defineProperty(this, "RH", {value: "Richard Headkid", writable: false}); }
but that would be very silly and possibly confusing, as it doesn't prevent you from accidentally declaring a variable with the same name as the property.
Thinking about it...
if (typeof(testRH) === 'undefined'){ const testRH = "Richard Headkid"}
This will create a constant, testRH, that exists only inside the curly braces, so not a lot of use.
Wow! Object.defineProperty is useful for more than just tracking changes :p
(Thinking about it… if I was trying to make a library that would me to convert an old .aslx file to work with this new engine, how would be best to implement changescripts? Would I need to abuse defineProperty excessively, or is there some system already implemented that would take care of it?)
There is nothing currently implemented like that. I was not aware Object.defineProperty could be used like that.
how would be best to implement changescripts?
Pixie says:
https://github.com/ThePix/QuestJS/wiki/Outstanding-Features#change-scripts
EDIT
Oh. Pixie actually said something in response to that before my page refreshed. (Hehehe.)
If something could be done that would be great because, as mrangel says, it would help when translating from 5 to 6. However, it would be a fairly fundamental change at this stage, with a lot of changes across the whole system.
I poked around at it for a minute, but I couldn't get anything but errors.
I wonder how using Object.defineProperty for a change script on something like game.player.hitpoints would work . . .
I read the Mozilla page. I sort of understand setters and getters (I think), until they start criss-crossing them and doing crazy stuff. That site tends to go from 0 to 50, leaving me on the side of the road.
I'd probably do something like:
function enableChangescripts (obj, attr, script=null) {
// don't define the property twice
if (!obj.hasOwnProperty("_real_"+attr)) {
// preserve the existing value of the attribute if it has one
// and make this property non-enumerable so it doesn't show up in `foreach`
Object.defineProperty(obj, "_real_"+attr, {value: (obj.hasOwnProperty(attr) ? obj[attr] : undefined), writable: true, enumerable: false});
Object.defineProperty(obj, attr, {
get: function () {
return (this["_real_"+attr]);
},
set: function (val) {
var oldvalue = this["_real_"+attr];
this["_real_"+attr] = val;
if (typeof this["changed"+attr] === 'function') {
this["changed"+attr].call(this, oldvalue);
}
}
});
}
if (typeof script === 'function') {
this["changed"+attr] = script;
}
}
(simplest construction I can see to make it work like it does in 5.8; takes an object reference, an attribute name, and optionally a changescript. Then makes an underlying "real" property that would be something like game.player._real_hitpoints. You can bypass the changescripts by setting the real property directly. The real property doesn't show up if you foreach over the object or use .keys()/.values() because it isn't enumerable; but you can find it using Object.getOwnPropertyNames(obj) for the purposes of loading/saving)