3

I have the function:

isset = function(obj){
  alert(obj !== undefined);
 }

Then when I do isset(defined_variable) where defined_variable has been declared, the alert box shows true but when I do isset(undefined_variable) where undefined_variable has not been declared, the alert box does not show at all, while I expected the alert box to show false. What am I doing wrong? I have tried using typeof but the results are the same.

Supreme Dolphin
  • 2,248
  • 1
  • 14
  • 23
  • 6
    Using an undeclared variable throws an error in javascript, you can see it if you open your console (F12) – adeneo Jan 04 '16 at 09:18
  • Show us the exact attempt you made using `typeof`. –  Jan 04 '16 at 09:19
  • 2
    The whole purpose of such function makes very little sense. There is a chance you're trying to solve the *original problem* in a very wrong way. So, if this is supposed to be a solution - it's highly recommended that you explained the real problem so that the community helped you to solve it *properly* – zerkms Jan 04 '16 at 09:20
  • @torazaburo With `typeof`, what I did was `alert(typeof undefined_variable !== "undefined") `. – Supreme Dolphin Jan 04 '16 at 09:51
  • The problem is, that in order to be passed to the `isset` function without generating a `ReferenceError`, it must already be declared. Did you declare it? If you did, what you show should work fine. –  Jan 04 '16 at 10:28

3 Answers3

4

That's because there's a difference between undefined and undeclared.

var foo; // foo is undefined.
// bar is undeclared.

console.log(foo === undefined); // true
try {
  console.log(bar === undefined);
} catch (e) {
  console.error('I had an error!'); // gets invoked.
}

foo = 'something';
console.log(foo === undefined); // false
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • 1
    Why would you ever have an undeclared variable in your code? – Madara's Ghost Jan 04 '16 at 10:04
  • Under some circumstances, such as when I'm using one javascript file for several pages. When using `document.getElementById('some-object-id')` for example, there are some pages that won't have `some-object-id`. – Supreme Dolphin Jan 04 '16 at 10:16
  • 2
    @TroubleZero When an id is not present in the DOM, `getElementById` returns `null`, isset does not check for `null` value it only checks for `undefined` values – axelduch Jan 04 '16 at 10:23
1

but when I do isset(undefined_variable) where udefined_variable has not been declared, the alert box does not show at all, while I expected the alert box to show false

because it throws an error in your console (check your console) that this variable that you are comparing is not defined.

Uncaught ReferenceError: 'c' is not defined

i tried with isset( c ) and c was not declared first

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
1

When you dereference an undeclared variable (meaning you try to use a symbol that was never wrote before), you get a Reference error.


There are several ways to deal with this, but you can't determine what are local variables in javascript. Thus, your problem can be solved dynamically only for global variables, or a given scope object.

No functions could handle local scope dynamically.


You can prefix it with window if you are in a browser context (for more context see this SO answer about global object in javascript)

This would not modify your isset function code:

isset(window.undefined_variable)

There would be another way, which would need that isset function changes, but uses the same principle (still in browser context):

isset('undefined_variable_name_wrawppped_in_a_string')

function isset(name) {
    return name in window;
}

We can't really use typeof in isset, it's sad because it would be convenient since it doesn't throw a Reference Error when the variable was never declared. We could still use a form of eval to do it, but since I don't want us to go there, I won't implement it.

But now, what if you want to check several nested properties?

function isset (memoryPath, root) {
    var nodeNames = memoryPath.split('.');
    var expectedDepthReached = nodeNames.length;
    var depthReached = 0;
    var nodeName;
    var node = root;

    // we are gonna read it from left to right
    // using Array.prototype.pop()
    // reversing it will alow us to do so
    nodeNames.reverse();

    do {
        nodeName = nodeNames.pop();
        node = node[nodeName];

        if (node) {
            depthReached++;
        }
    } while (node);

    return depthReached === expectedDepthReached;
}

And an exemple:

window.myGlobals = {
    path: {
        to: {
            a: {
                variable: true
            }
        }
    }
};

isset('myGlobals.path.to.a.variable', window), // true
isset('myGlobals.path.foo', window) // false
Community
  • 1
  • 1
axelduch
  • 10,769
  • 2
  • 31
  • 50