[SOLVED] Can I check if a const exists in JS before declaring it if it does not?
![](https://i.imgur.com/WUGXS8yb.png)
Richard Headkid
18 Dec 2020, 12:44The 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 Pixie
18 Dec 2020, 13:32The 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.
![](https://i.imgur.com/WUGXS8yb.png)
Richard Headkid
18 Dec 2020, 14:22The second is the right approach, but I suggest [ . . . ]
Cool, cool.
log
should 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!
![](https://i.imgur.com/WUGXS8yb.png)
![](https://i.imgur.com/WUGXS8yb.png)
Richard Headkid
18 Dec 2020, 14:39EDIT
This is not it!
See this post for the correct answer.
Got it!
if (typeof(RH) === 'undefined'){ window["RH"] = "Richard Headkid"}
mrangel
18 Dec 2020, 15:20I know the first one won't work because I couldn't declare a
const
in theif
block even iflog
wasn'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.
The Pixie
18 Dec 2020, 15:27Thinking 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.
![](https://i.imgur.com/WUGXS8yb.png)
mrangel
18 Dec 2020, 17:41Wow! 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?)
The Pixie
18 Dec 2020, 18:03There is nothing currently implemented like that. I was not aware Object.defineProperty
could be used like that.
![](https://i.imgur.com/WUGXS8yb.png)
Richard Headkid
18 Dec 2020, 18:16how 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.)
The Pixie
18 Dec 2020, 19:28If 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.
![](https://i.imgur.com/WUGXS8yb.png)
Richard Headkid
18 Dec 2020, 19:35I 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.
mrangel
18 Dec 2020, 20:35I'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)