JavaScript For In Madness
Have you never instinctively written a for in loop like the next one, instantly correcting it since you need a variable to perform it?
This quick post talks about above nonsense case providing a solution I will explain only if anybody will be interested about it, since (I am quite lazy and tired right now and ...) I think I've been able to solve the trick using almost every JavaScript bad practice :D
In few words we don't need to define the "o" object in any place. The trick works as expected with blocked properties, as length is for a function, name, and whatever else was assigned to the object and even nested
Isn't it cool? Even with Arrays!
The good part is that break will work as expected and the changed object is quite static since it is a function, looped over original object properties.
What would be truly nice in my opinion is the possibility to implement this kind of syntax:
Something similar to PHP world where we have:
I am pretty much sure JavaScript will never implement above syntax but hey, that's why I have created a monster I'll probably never use in my programming life :P
The main trick about supported length property is described in this post.
for(var k in {oops:null}){
// cool, got "k" here ...
// now how do I get
// the bloody "oops" value?
}
This quick post talks about above nonsense case providing a solution I will explain only if anybody will be interested about it, since (I am quite lazy and tired right now and ...) I think I've been able to solve the trick using almost every JavaScript bad practice :D
Runtime Assigned For In Loop
(function(self, Function){
// Another (C) WebReflection Silly Idea
"use strict"; // Mit Style Weirdness
var $o;
self.o = function o($){
if(!$)
self.o = $o;
else {
$o = self.o;
self.o = Function(
"$", "return function o(" +
new Array(($.length || 0) + 1).join(",k").slice(1) +
"){return $(arguments[0])}"
)(o);
for(var k in $)
self.o[k] = $[k]
;
};
return $;
};
})(this, Function);
WTF Is That
Above agglomerate of dynamic assignments/compositions let us perform a forIn without creating (virtually speaking) a variable. How?
for(var k in o({a:"b", c:"d"})){
alert([k, o[k]]);
};
In few words we don't need to define the "o" object in any place. The trick works as expected with blocked properties, as length is for a function, name, and whatever else was assigned to the object and even nested
for(var k in o({
length:123,
name:"test"
})){
alert([k, o[k]]);
// nested for in ...
for(var k in o({a:"b"}))
alert([k, o[k]])
;
o(); // back in town parent object
alert(o.name); // test
};
Isn't it cool? Even with Arrays!
for(var k in o([1, 2, 3])){
alert([k, o[k]]);
// 0,1
// 1,2
// 2,3
};
The good part is that break will work as expected and the changed object is quite static since it is a function, looped over original object properties.
Why This Abomination
Well, let's say with let and var we can do what we want in a generic for loop but we are kinda stuck with a single variable with a "for in" one.What would be truly nice in my opinion is the possibility to implement this kind of syntax:
for(var o = {a:"b"}, k; k in o){
// common loop with o and o[k]
};
Something similar to PHP world where we have:
foreach(array('a'=>'b') as $key => $value){
// do stuff and forget about the config variable
}
I am pretty much sure JavaScript will never implement above syntax but hey, that's why I have created a monster I'll probably never use in my programming life :P
The main trick about supported length property is described in this post.
Labels: for in, JavaScript, runtime



6 Comments:
Nice post :)
A couple of questions...
Does your implementation works with n-depth nested levels? I kind of tested it with this example and it doesn't seem to work:
for(var k in o({
length:123,
name:"test"
})){
alert([k, o[k]]);
// nested for in ...
for(var k in o({a:"b"})) {
alert([k, o[k]]);
for(var kk in o({'newkey':50})) {
alert([kk, o[kk]]);
}
o();
alert(["a", o.a]);
}
o();
alert(["len", o.length]);
};
I modified just a little bit the code and it seemed to work fine like this:
(function(self, Function){
// Another (C) WebReflection Silly Idea
"use strict"; // Mit Style Weirdness
var $o = [];
self.o = function o($){
if(!$)
self.o = $o.pop();
else {
$o.push(self.o);
self.o = Function(
"$", "return function o(" +
new Array(($.length || 0) + 1).join(",k").slice(1) +
"){return $(arguments[0])}"
)(o);
for(var k in $)
self.o[k] = $[k]
;
};
return $;
};
})(this, Function);
...but I'm not sure it's right.
Also, I kind of had a couple of problems with the "name" function property in the example. Does this have to do with the fact that "name" is a reserved property for Function objects?
Wow, that is some crazy stuff. I guess this is what you need the ECMAScript certification for... :D
I would not want to see that monstrosity in any production code though.
me neither ;)
Weeeeee! Thanks for the challenge Andrea, that was a fun lunch time effort for me.
for(var k in a = {oops:null}){
console.log(k);
console.log(a[k]);
}
Ok, I only tested it in Firefox, Opera, and Safari so it may barf in ie.
Josh, you have created a global "a" object in that way :-)
Very true, but it didn't let me scope it with a var in front.
// This doesn't work.
for(var k in var a = {oops:null}){
console.log(k);
console.log(a[k]);
}
I guess the way around that is
var a = {oops:null};
for (var k in a) {
}
But that doesn't let you have a one line control statement.
Post a Comment
Links to this post:
Create a Link
<< Home