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:
$('foo')
looks elements tagfoo
— there nofoo
html tag. perhaps meant#foo
or.foo
(or perhapsfoo
meant stand-indiv
orspan
or whatever).your
foo
property's value jquery object, no need wrap in$()
call.this
has no special meaning within object initializer, it's samethis
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:prior step-by-step code in scope, variable called
myobject
created valueundefined
.when expression reached in step-by-step execution of code, start assignment expression evaluating right-hand side (the bit after
=
).to start object initializer expression, new object created not stored anywhere.
each property initializer in object initializer processed in source code order (yes, that's guaranteed spec), so:
evaluate expression defining property.
create property on object using given key , evaluated value.
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
Post a Comment