[SOLVED] Can I check if a const exists in JS before declaring it if it does not?

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: image


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.

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!


UPDATE

if (typeof(testRH) === 'undefined'){ const testRH = "Richard Headkid"}

That doesn't work if testRH does not exist. (It doesn't throw an error either way, though.)


image


EDIT

This is not it!

See this post for the correct answer.


Got it!

if (typeof(RH) === 'undefined'){ window["RH"] = "Richard Headkid"}

image


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

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.


Ha.

I checked if it existed, but not if it could be modified.

This is the solution:

if (typeof(RH) === 'undefined'){ Object.defineProperty(this, "RH", {value: "Richard Headkid", writable: false}); }

image


Whoo-hoo!

Thanks, guys!


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)


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums