JavaScript: issue met object naam

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • SideShow
  • Registratie: Maart 2004
  • Laatst online: 16-06 15:55

SideShow

Administrator

Topicstarter
Hallo

Ik heb nogal veel script in mijn huidige project en werk daardoor met zogenaamde namespaces (in feite objecten).
Om het mezelf makkelijker te maken (kijken als namespace al bestaat, en functie aanmaken in desbetreffende object) heb ik het window object een "namespace"-functie.


JavaScript:
1
2
3
4
5
6
7
8
9
10
function namespace(input) {
    var names = input.split('.').reverse();
    (function makeNamespace(currentObject, childObjectName) {
        if (currentObject && childObjectName) {
            currentObject[childObjectName] = currentObject[childObjectName] || {};
            makeNamespace(currentObject[childObjectName], names.pop());
        }
    })(window, names.pop());
    return eval(input);
}


Dit stelt me in staat om het volgende te vervangen:

ik = ik || {};
ik.ben = ik.ben || {};
... enzovoort

door:

namespace("ik.ben.een.namespace").Person = function() { }

Nu de probleemomschrijving:
Gebruik in views en/of lokale script(files): var p = new ik.ben.een.namespace.Person();
Als je vervolgens "p" intikt in de chrome console: krijg je de constructor/object type te zien, dacht ik.
In dit geval zal dat "namespace.Person" zijn en niet "ik.ben.een.namespace.Person".

Dit laatste kan je wel bekomen indien je hetvolgende doet:
namespace("ik.ben.een.namespace");
ik.ben.een.namespace.Person = function() { }

Maar op deze manier verlies je al de helft van het gemak.

Concreet, de vraag: iemand die hier meer info over kan geven?
Ik heb dus geen directe technische problemen, alleen een informatie request :)

[ Voor 3% gewijzigd door SideShow op 12-11-2012 16:16 ]


Acties:
  • 0 Henk 'm!

  • boe2
  • Registratie: November 2002
  • Niet online

boe2

'-')/

Ik snap weinig van wat je daar doet, maar haal je nu niet namespaces en classes door elkaar?

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.' - Pratchett.


Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 15-07 12:31
Ik zou voorzichtig zijn met namespace als functie naam te gebruiken. Zou eerder iets doen als createNamespace.

Maar probleem blijft bestaan inderdaad. Komt omdat je natuurlijk iets on-orthodox doet ;-).

[ Voor 71% gewijzigd door McVirusS op 12-11-2012 16:57 ]


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • SideShow
  • Registratie: Maart 2004
  • Laatst online: 16-06 15:55

SideShow

Administrator

Topicstarter
Boeboe schreef op maandag 12 november 2012 @ 16:39:
Ik snap weinig van wat je daar doet, maar haal je nu niet namespaces en classes door elkaar?
namespaces is het concept en bestaat niet in javascript - je kan het wel nabootsen met objecten
het gevolg is dat je hele object/functie library in 1 root object kan zitten. dat kan natuurlijk ook zonder dat functie'tje van mij, maar dan moet je steeds overal checken als de "namespace" reeds bestaat. dat is lelijk en ook moeilijker te onderhouden.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 12-07 22:24
SideShow schreef op maandag 12 november 2012 @ 17:03:
[...]

dat kan natuurlijk ook zonder dat functie'tje van mij, maar dan moet je steeds overal checken als de "namespace" reeds bestaat. dat is lelijk en ook moeilijker te onderhouden.
En `eval` is niet lelijk, zullen we zeggen?

Doe het dan netjes door gewoon de context te tracken in een variable. Kun je gelijk ook die onnodige recursie vermijden en de optie geven om een context anders dan `window` te gebruiken.

Off the top of my head, zoiets:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
function createNS( ns, context ) {
  var name, names;

  names = ns.split(".") || [];
  context = context || window;
  
  while( names.length ) {
    name = names.shift();
    context = ( context[ name ] = context[ name ] || {});    
  }

  return context;
}

Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 15-07 12:31
Chrome's console.log heeft zijn eigen methode om objecten een naam te geven in de console. Vreemd genoeg gebruikt hij hier niet eens de toString() functie voor (wat wel logisch zou zijn).

Dit levert wel enigszins bruikbare console.log output op maar is wel best wel ugly.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function createNS( ns, context ) { 
  var name, names; 

  names = ns.split(".") || []; 
  context = context || window; 
   
  while( names.length ) { 
    name = names.shift(); 
    context = ( context[ name ] = context[ name ] || {});     
  } 
    
  context.__proto__.namespace = ns;
  context.__proto__.toString = function() { return this.namespace; }
  return context; 
}

createNS("ik.ben.een.namespace").Person = function() {
  this.namespace = this.namespace; // this is needed for extra output in console.log
};
        
var p = new ik.ben.een.namespace.Person();
console.log(p.toString());
console.log(p);

[ Voor 4% gewijzigd door McVirusS op 12-11-2012 17:53 ]


Acties:
  • 0 Henk 'm!

  • SideShow
  • Registratie: Maart 2004
  • Laatst online: 16-06 15:55

SideShow

Administrator

Topicstarter
niks mis met eval, zolang je het niet gebruikt voor user generated content lijkt me

*edit: even de context methode van je bekeken: dat is een leuke manier. dank daarvoor.

[ Voor 35% gewijzigd door SideShow op 12-11-2012 20:17 ]


Acties:
  • 0 Henk 'm!

  • pieturp
  • Registratie: April 2004
  • Laatst online: 13-07 19:55

pieturp

gaffa!

Behalve 't door je aangehaalde veiligheidsrisico, is 't ook gewoon traag. Beter blijf je er af als je 't niet nodig hebt.

Hier mijn "namespacing" aanpak:

JavaScript:
1
2
3
4
5
6
7
8
function registerNS(namespace, scope){
        scope = typeof scope == 'undefined' ? window : scope;
        if (typeof scope[namespace] == 'undefined') {
            return (scope[namespace] = {});
        } else {
            return scope[namespace];
        }
    }

... en etcetera en zo


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 12-07 22:24
pieturp schreef op maandag 12 november 2012 @ 23:14:
[...]
Behalve 't door je aangehaalde veiligheidsrisico, is 't ook gewoon traag.
Tot op 100x langzamer dan 'normaal' geschreven JavaScript code zelfs! Daarnaast wordt code die van `eval` gebruik maakt in de regel ook niet aan de optimizing compilers in de nieuwere JavaScript engines aangeboden. Dus `eval` wil je nooit, maar dan ook nooit gebruiken. Als je genoodzaakt bent om dynamic code te emitten, dan gebruik je de `Function` constructor en niets anders.

Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 18-03 09:33

_Thanatos_

Ja, en kaal

De Function constructor is een eval in schaapskleren. Geldt ook voor de setTimeout en setInterval functies met string-argument, en html-event-attributen.

日本!🎌


Acties:
  • 0 Henk 'm!

  • Tarilo
  • Registratie: December 2007
  • Laatst online: 15-07 16:23
Ik wil geen discussie beginnen over het goed of fout van eval. Ik ben eval echter nog nooit tegengekomen in een situatie waar het echt nodig was, wat mij betreft is het dan ook een dik vet uitroepteken!! dat er iets niet klopt.

En ja er zal vast een situatie te bedenken zijn waar eval de oplossing is, maar mijn punt is: Als je eval nodig hebt, kijk eerst of het niet anders kan.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 12-07 22:24
_Thanatos_ schreef op dinsdag 13 november 2012 @ 01:14:
De Function constructor is een eval in schaapskleren. Geldt ook voor de setTimeout en setInterval functies met string-argument, en html-event-attributen.
Nee. De code in de Function constructor wordt anders afgehandeld dan de code in een eval. Het is nog steeds wel langzaam, maar significant minder langzaam dan eval. (20x tegen 100x in Google's V8 engine, meen ik me te herinneren van een benchmark.)

Omdat de Function constructor een nieuwe functie bakt, die een geisoleerde scope heeft, kan er toch nog op beperkte schaal een aantal optimalisaties toegepast worden waar dat bij eval niet kan (tenzij je in ES5 strict mode draait).
7laurens7 schreef op dinsdag 13 november 2012 @ 10:03:
Ik wil geen discussie beginnen over het goed of fout van eval. Ik ben eval echter nog nooit tegengekomen in een situatie waar het echt nodig was, wat mij betreft is het dan ook een dik vet uitroepteken!! dat er iets niet klopt.
Mee eens!
Het enige scenario waar dynamisch te emitten code echt een noodzaak is, is bij code generation (en daar is het eigen aan het probleemgebied.) Denk hierbij o.a. aan het client-side compileren van allerlei HTML templating talen, of het compileren van selectors voor JS-based query selector engines (voor oude browsers zoals IE7, die geen querySelectorAll implementatie hebben, of browsers die bugs in de native implementatie hebben).

Een zeer modern scenario is het emitten v/e function body naar een HTML5 worker thread, om op die manier een inline worker te maken.

(In al die gevallen kom je overigens goed toe met de Function constructor. Een rauwe eval zou echt nooit nodig moeten zijn.)

[ Voor 45% gewijzigd door R4gnax op 13-11-2012 20:29 ]


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 18-03 09:33

_Thanatos_

Ja, en kaal

Nee. De code in de Function constructor wordt anders afgehandeld dan de code in een eval. Het is nog steeds wel langzaam, maar significant minder langzaam dan eval. (20x tegen 100x in Google's V8 engine, meen ik me te herinneren van een benchmark.)

Omdat de Function constructor een nieuwe functie bakt, die een geisoleerde scope heeft, kan er toch nog op beperkte schaal een aantal optimalisaties toegepast worden waar dat bij eval niet kan (tenzij je in ES5 strict mode draait).
Er kan nog steeds potentiëel gevaarlijke code in terecht komen. Dus snel of niet, het is dynamische compilatie waarbij je HEEL ERG GOED moet bedenken waar de geïnjecteerde code vandaan komt / hoe het samengesteld wordt. Maar evil is het daardoor zeker wel.

日本!🎌

Pagina: 1