Suis-je en train de faire quelque chose de mal ou est-ce simplement impossible:

(function(namespace,undefined)
{
    //Private properties and methods
    var foo="bar";
    function test(){return foo;}

    //Public properties and methods
    namespace.foobar=foo+"123";
    namespace.showFoo=function(){return test();};
})(window.namespace=window.namespace || {});

Ensuite, j'essaie "d'étendre" l'espace de noms ci-dessus et d'ajouter une nouvelle méthode:

(function(namespace,undefined)
{
    //Public method
    namespace.sayGoodbye=function()
    {
        alert(namespace.foo);
        alert(namespace.bar);
        alert(test());
    }
})(window.namespace=window.namespace || {});

L'alerte affiche undefined pour les propriétés et génère une erreur pour la méthode test().

Merci.

1
Francisc 12 oct. 2011 à 13:53

3 réponses

Meilleure réponse

Pourquoi vous attendez-vous à ce que foo et bar soient disponibles? Ces identifiants ne sont jamais attribués à votre objet namespace où que ce soit.

Toute variable déclarée avec var n'est disponible que dans la fonction (-Context) de l'activation / objet variable en cours. Il en va de même pour function declarations, dans votre cas, test(). Ces deux éléments sont uniquement stockés dans l'AO à partir de la première fonction anonyme et ne sont pas stockés dans votre objet namespace. Vous devez attribuer explicitement les valeurs

namespace.foo = foo;
namespace.bar = "hello I am bar";
3
jAndy 12 oct. 2011 à 10:06

Déclaration des espaces de noms et extension des espaces de noms:

var namespace = function(str, root) {
    var chunks = str.split('.');
    if(!root)
        root = window;
    var current = root;
    for(var i = 0; i < chunks.length; i++) {
        if (!current.hasOwnProperty(chunks[i]))
            current[chunks[i]] = {};
        current = current[chunks[i]];
    }
    return current;
};

// ----- USAGE ------

namespace('ivar.util.array');

ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);

namespace('string', ivar.util); //or namespace('ivar.util.string');

ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo); 

Essayez-le: http://jsfiddle.net/stamat/Kb5xY/

Article de blog: http://stamat.wordpress.com/2013 / 04/12 / javascript-elegant-namespace-declaration /

1
stamat 12 avril 2013 à 13:09

Vous avez plusieurs bogues dans votre code. Ce code fonctionne. Exemple.

(function(namespace)
{
    if(namespace === undefined) {
        window.namespace = namespace = {};
    }

    //Private properties and methods
    var foo="bar";
    function test(){return foo;}

    //Public properties and methods
    namespace.foobar=foo+"123";
    namespace.showFoo=function(){return test();};
})(window.namespace);

(function(namespace)
{
    if(namespace === undefined) {
        window.namespace = namespace = {};
    }

    //Public method
    namespace.sayGoodbye=function()
    {
        alert(namespace.foobar);
        alert(namespace.showFoo());
    }
})(window.namespace);

window.namespace.sayGoodbye();

Bugs: 1. Vous ne définissez jamais la variable window.namespace. 2. Si vous déclarez des variables / fonctions de manière privée dans une fonction, seule cette fonction spécifique peut accéder à ces variables / fonctions. Si vous souhaitez utiliser un espace de noms, vous pouvez le faire comme ceci:

var namespace = (function(){
        var private = "private";
        function privateFunc() {
                return private;
        }
        return {
            "publicFunc": function(){return privateFunc()}
        }
    })();
namespace.publicFunc() === "private";
//alert(namespace.publicFunc());


// extend namespace
(function(namespace){
    var private = "other private";
    namespace.newFunc = function(){return private};
})(namespace);
namespace.newFunc() === "other private";
//alert(namespace.newFunc());
1
styrr 12 oct. 2011 à 10:26