2010-09-03 7 views
4

J'essaie de créer un moyen d'ajouter des fonctions sous un espace de noms spécifique (dpcom). Cela peut être en notation point selon ce que l'utilisateur a fait dans son fichier javascript. Donc, en gros, ce que je veux qu'ils fassent quelque chose comme ceci:Suggestions pour rendre ce bit de code Javascript plus sexy?

dpcom.library('something.foo.funcName', function() { 
    // Code goes here. 
}) 

Ils peuvent alors appeler leurs trucs plus tard comme:

dpcom.something.foo.funcName(); 

qui exécutera le code qu'ils ont défini ci-dessus. Le code que je veux aider à en faire plus sexy est ici (il utilise jQuery):

dpcom.library = function(name, func) { 
    root = dpcom; 
    objects = name.split('.'); 
    lastElement = objects[objects.length - 1]; 

    $(objects).each(function(idx, elem) { 
     if (elem == lastElement) { 
      root[elem] = func; 
     } else if (!root[elem]) { 
      root[elem] = {} 
     } 
     root = root[elem]; 
    }); 
} 

Cela devrait gérer la notation de points possible et créer des objets à l'intérieur de mon espace de noms si elles ne sont pas déjà (Je ne Je ne veux pas écraser les objets déjà déclarés).

Le code que j'ai ci-dessus semble bien fonctionner, mais j'ai le sentiment que je peux le rendre meilleur mais mon cerveau ne me dit pas où ... Quelqu'un veut-il essayer de le faire?

+6

Si vous pensez que le code peut être sexy, vous êtes au-delà de l'aide de l'OMI ;-) –

+4

code peut certainement être sexy. – Stephen

+1

Je suis entièrement d'accord ... Je suis au-delà de l'aide à ce stade. :) – intargc

Répondre

3

Vous devriez être en mesure de le faire d'une manière un peu plus attrayante en utilisant shift():

dpcom.library = function(name, func) { 
    var root = dpcom, 
     objects = name.split('.'), 
     elem; 

    while (elem = objects.shift()) { 
     if (objects.length) { 
      if (!root[elem]) 
       root[elem] = {}; 
      root = root[elem]; 
     } 
     else 
      root[elem] = func; 
    } 
} 

De cette façon, vous pouvez abandonner l'exigence jQuery. Aussi, n'oubliez pas de déclarer explicitement vos vars avec le mot-clé var.

En fonction de votre définition du code sexy, vous pouvez également remplacer ce bloc:

 if (objects.length) { 
      if (!root[elem]) 
       root[elem] = {}; 
      root = root[elem]; 
     } 

avec:

 if (objects.length) 
      root = !root[elem] ? root[elem] = {} : root[elem]; 
1

est ici un coup de poignard à elle

dpcom.library = function(name, func) { 
    var lastElement, root = dpcom, objects = name.split(/\./); 
    lastElement = objects[objects.length - 1]; 

    $.each(objects, function(idx, elem) { 
     if (!root[elem]) { 
      if (elem == lastElement) { 
       root[elem] = func; 
      } else { 
       root[elem] = {} 
       root = root[elem]; 
      } 
     } 
    }); 
} 

EDIT:

Je me suis trouvé en utilisant la méthode de prolonger jQuery pour cela. Consultez les documents here.

0

Je ne sais pas si cela est plus sexy ou plus lisible, mais il n'a pas besoin da la requête et n'a pas de vars mondiale;)

var dpcom = {'test': null, 'something': {}}; 
dpcom.library = function(name, func) { 
    for(var i = 0, node = this, names = name.split('.'), l = names.length; i < l; i++) { 
     node = node[names[i]] = ((i == l - 1) ? func : node[names[i]] || {}); 
    } 
}; 

dpcom.library('something.foo.funcName', function() { 
    // Code goes here. 
}); 

Résultat:

{ test: null 
, library: [Function] 
, something: { foo: { funcName: [Function] } } 
} 
3

Est-ce une sorte de code-golf bizarre?

Essayez ceci, cela pourrait fonctionner ...

dpcom.library = function(name, func) { 
    var p = name.split('.'), e, root = this; 
    while (e = p.shift()) root = root[e] = root[e] || (!p.length ? func : {}); 
} 
+0

+1 pour 'split' en utilisant un' String', pas un 'RegExp'. –

0

Découvrez la fonction d'espace de noms de YUI 2:

YAHOO.namespace('myNS').funcName = function(){/* do something with arguments */}; 
1

En utilisant la méthode reduce pour les tableaux,

dpcom.library = function(key, value) { 
    var objects = key.split('.'); 
    var leaf = objects.pop(); 

    var constructHierarchy = function(object, property) { 
     return (object[property] = object[property] || {}); 
    }; 

    objects.reduce(constructHierarchy, dpcom)[leaf] = value; 
}; 

Pour augmenter le facteur de sex-appeal, font la deuxième valeur générique et non seulement fonction. Il est déjà fait dans toutes les réponses, mais d'être explicite à ce sujet :) aide

dpcom.library('awesome.object', { foo: 'woah' }); 
Questions connexes