jquery - Bulk Declare JavaScript Associative Array -


is there way bulk set associative array keys , values in javascript, similar php's shorthand array declaration below?

$array = [   'foo' => 'val1',   'bar' => 'val2',   'baz' => 'val3' ]; 

the way can think of declare associative arrays in js this:

var newarray = new array(); newarray['foo'] = 'val1'; newarray['bar'] = 'val2'; newarray['baz'] = 'val3'; 

or this:

var newarray = new array(),   keys = ['foo', 'bar', 'baz'],   vals = ['val1', 'val2', 'val3'];  for(var = 0; < keys.length; i++) {   newarray[ keys[i] ] = vals[i]; } 

that last 1 can cause mess in cases, wanted list since it's doable.

if there isn't way top example, that's fine. would've been nice. tried using js object literal jquery this:

var myobject = {   foo: $('foo'),   bar: $(this.foo).find('bar'),   baz: $(this.bar).data('baz') } 

unfortunately seems js object literals don't allow evaluating code set values properties. if turned properties methods returned values instead of permanently storing values/references in properties, have run every time they're called; don't want if possible.

thanks in advance.

php's "associative arrays" — ordered set of name/value pairs — rare data structure, particularly rare find feature of language rather library class. javascript doesn't have them — yet. es6 introduce better iteration semantics language generally, , standard library map type takes advantage of semantics when iterated, visits entries in key insertion order; more below.

before es6

until es6, can use objects, seem know, so:

var obj = {   foo: 'val1',   bar: 'val2',   baz: 'val3' }; 

...but properties have no order. if order important, you'd have track order separately, perhaps having keys in array:

var keys = ['foo', 'bar', 'baz']; var obj = {   foo: 'val1',   bar: 'val2',   baz: 'val3' }; var i; (i = 0; < keys.length; ++i) {     console.log(obj[keys[i]]); } 

this less delicate parallel arrays, because have worry order of one array.

as of es6

es6's map defines when iterated, map's entries visited in order in keys inserted. can initialize map instance using array of key/value arrays, so:

var map = new map([     ["foo", "val1"],     ["bar", "val2"],     ["baz", "val3"] ]); 

so equivalent form when it's widely-supported.

more map in this article (and the draft spec).


unfortunately seems js object literals don't allow evaluating code set values properties

yes, do. in example, foo property jquery object set of elements matching css selector foo (a set empty, there no foo element).

example:

var obj = {     foo: 6 * 7 }; console.log(obj.foo); // 42 

you can't (yet) use expression property name in property initializer that, value. in es6, you'll able use expression property name well:

// of es6 var obj = {     ['f' + 'o' + 'o']: 6 * 7 }; console.log(obj.foo); // 42 

meanwhile, in es5 can it, not in initializer:

// var obj = {}; obj['f' + 'o' + 'o'] = 6 * 7; console.log(obj.foo); // 42 

i tried using js object literal jquery this:

var myobject = {   foo: $('foo'),   bar: $(this.foo).find('bar'),   baz: $(this.bar).data('baz') } 

there couple of problems there:

  1. $('foo') looks elements tag foo — there no foo html tag. perhaps meant #foo or .foo (or perhaps foo meant stand-in div or span or whatever).

  2. your foo property's value jquery object, no need wrap in $() call.

  3. this has no special meaning within object initializer, it's same this outside object initializer, not reference object being initialized. malk's suggestion not work, because of when properties being initialized, myobject hasn't had value assigned yet. here's how overall expression above evaluated:

    1. prior step-by-step code in scope, variable called myobject created value undefined.

    2. when expression reached in step-by-step execution of code, start assignment expression evaluating right-hand side (the bit after =).

    3. to start object initializer expression, new object created not stored anywhere.

    4. each property initializer in object initializer processed in source code order (yes, that's guaranteed spec), so:

      1. evaluate expression defining property.

      2. create property on object using given key , evaluated value.

    5. when object initializer complete, resulting value (the object reference) assigned myobject.

to refer properties of object expressions defining other properties of object, have series of statements rather single statement:

var myobject = {   foo: $('foo') // or $('#foo') or $('.foo') or whatever }; myobject.bar = myobject.foo.find('bar'); myobject.baz = myobject.bar.data('baz'); 

alternately, convoluted temporary variables:

var foo, bar, myobject = {   foo: (foo = $('foo')),   bar: (bar = foo.find('bar')),   baz: bar.data('baz') }; 

...because result of assignment expression value assigned. (no enduring connection between properties , variables maintained.) have temp variables lying around. wrap entire thing in function temp vars around temporarily:

var myobject = (function() {   var foo, bar;   return {     foo: (foo = $('foo')),     bar: (bar = foo.find('bar')),     baz: bar.data('baz')   }; })(); 

...but that's getting pretty convoluted. :-)


re comment below:

are there limits on kind of expressions can evaluated property values?

no, expression processing values of property initializers same expression handling elsewhere in scope containing object initializer property initializer part of.

here's example grabbing dom elements via jquery:

var myobject = {    foo: $('.foo')  };  myobject.bar = myobject.foo.find('.bar');  myobject.baz = myobject.bar.data('baz');    myobject.foo.css("color", "green");  myobject.bar.css("color", "blue");  $("<div>").html(myobject.baz).appendto(document.body); // "i'm data"
<div class="foo">    .foo    <div class="bar" data-baz="i'm data">      .bar inside .foo    </div>  </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

side note: wouldn't use .data if you're doing accessing data-* attributes; i'd use attr instead. data sets data cache object, initializes cache all data-* attributes on object, , works cache, not attributes. overkill if you're reading attribute value.

or using convoluted function:

var myobject = (function() {    var foo, bar;    return {      foo: (foo = $('.foo')),      bar: (bar = foo.find('.bar')),      baz: bar.data('baz')    };  })();    myobject.foo.css("color", "green");  myobject.bar.css("color", "blue");  $("<div>").html(myobject.baz).appendto(document.body); // "i'm data"
<div class="foo">    .foo    <div class="bar" data-baz="i'm data">      .bar inside .foo    </div>  </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

[C++][SFML 2.2] Strange Performance Issues - Moving Mouse Lowers CPU Usage -

ios - Possible to get UIButton sizeThatFits to work? -