简体   繁体   中英

javascript best practice define variable (namespace) check is not already defined

Wanted to get opinions from the experts, I am declaring a variable that will act as the namespace for my application javascript code, but i want to check it is not already defined.

this code is terse and 'seems' to work - any reason I should avoid this and use typeof 'undef' checking instead?

var MY_NAMESPACE = MY_NAMESPACE || {};

Thanks

This is the standard way of doing it. See Matt Snider's analysis of the YUI YAHOO.namespace function which uses this same check (Also for a look at how to make it easy to create namespaces).

Matt's code, which he adapted from YUI to namespace off the window object instead of the YAHOO object:

window.object_mes_namespace = function() {   
    var a = arguments,    
        o = window,   
        i = 0,   
        j = 0,   
        tok = null,   
        name = null;   

    // iterate on the arguments   
    for (i = 0; i < a.length; i = i + 1) {   
        tok = a[i].split(".");   

        // iterate on the object tokens   
        for (j = 0; j < tok.length; j = j + 1) {   
            name = tok[j];             
            o[name] = o[name] || {};   
            o = o[name];   
        }   
    }   

    return o;   
}  

Note the o[name] = o[name] || {}; o[name] = o[name] || {}; line, which parallels your example.

Although what you posted is seen commonly, I personally don't think it's the best way to do it.

  1. MY_NAMESPACE could evaluate to false for several reasons other than undefined -- the variable could really be defined but be 0 or false or an empty string, and you might end up replacing this value.

  2. MY_NAMESPACE could evaluate to true for several reasons other than already being an object -- it could be a non-zero number or true or a string, and this will cause your script to silently fail, because adding properties to a primitive will fail without an error.

Really, the best way depends on what your goal is. If you don't want to pollute an existing variable/namespace, you should do a typeof check and stop if the variable is already defined but not an object:

if (typeof MY_NAMESPACE == 'undefined') {
  // create a new namespace
  MY_NAMESPACE = {};
}

if (typeof MY_NAMESPACE == 'object') {
  // go ahead
} else {
  // MY_NAMESPACE was already defined, but it is not an object
  // your script will fail if you continue, so do what you must and stop
}

If your script must work, just blindly create the namespace without any checks (of course, I'm not recommending that you do this).


Edit: (in response to @jball's comment, thought I'd just add it here)

  • If this namespace is part of a library that you're developing, then it is imperative that you name your namespace carefully to avoid collision. If you do encounter a collision, it's better to just stop loading your library than mix your library with another and get unexpected results.

  • If this namespace is just for your own application, it should be fairly simple to pick a name that isn't used by any libraries that you're using.

This is already the preferred way.

But your statement does nothing, unless you leak MY_NAMESPACE into another scope, because MY_NAMESPACE is MY_NAMESPACE .

I like the YUI example and use it for all my Apps. In yours, you're re-assigning MY_NAMESPACE no matter what, which isn't a huge deal, but I prefer to avoid that assignment if it's not necessary.

if (typeof myNamespace == "undefined" || !myNamespace) {
    var myNamespace = {};
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM