Friday 15 January 2010

javascript - Obtain the same result as a for..in loop, without any for..in loop -



javascript - Obtain the same result as a for..in loop, without any for..in loop -

(let suppose there reason wishing this. see end of question if want read reason.)

i obtain same result for in loop, without using language construct. result mean array of property names (i don't need reproduce behavior happen if modify object while iterating on it).

to set question code, i'd implement function without for in:

function getpropertiesof(obj) { var props = []; (var prop in obj) props.push(prop); homecoming props; }

from understanding of ecmascript 5.1 specification the in statement , the object.keys method, seems next implementation should correct:

function getpropertiesof(obj) { var props = []; var alreadyseen = {}; // handle primitive types if (obj === null || obj === undefined) homecoming props; obj = object(obj); // each object in prototype chain: while (obj !== null) { // add together own enumerable properties have not been seen yet var enumprops = object.keys(obj); (var = 0; < enumprops.length; i++) { var prop = enumprops[i]; if (!alreadyseen[prop]) props.push(prop); } // add together own properties (including non-enumerable ones) // in alreadyseen set. var allprops = object.getownpropertynames(obj); (var = 0; < allprops.length; i++) alreadyseen[allprops[i]] = true; // go on object's prototype obj = object.getprototypeof(obj); } homecoming props; }

the thought walk explicitly prototype chain, , utilize object.keys own properties in each object of chain. exclude property names seen in previous objects in chain, including when seen non-enumerable. method should respect the additional guarantee mentioned on mdn:

the object.keys() method returns array of given object's own enumerable properties, in same order provided for...in loop [...].

(emphasis mine)

i played bit implementation, , haven't been able break it.

so question:

is analysis correct? or overlooking detail of spec create implementation incorrect?

do know way this, match implementation's specific order of for in in cases?

remarks:

i don't care ecmascript < 5.1. i don't care performance (it can disastrous).

edit: satisfy @lexicore's curiosity (but not part of question), reason following. develop compiler javascript (from scala), , for in language build not part of things want back upwards straight in intermediate representation of compiler. instead, have "built-in" function getpropertiesof show first example. i'm trying rid of many builtins possible replacing them "user-space" implementations (written in scala). performance, still have optimizer "intrinsifies" methods, , in case intrinsify getpropertiesof efficient first implementation. create intermediate representation sound, , work when optimizer disabled, need true implementation of feature, no matter performance cost, long it's correct. , in case cannot utilize for in, since ir cannot represent build (but can phone call arbitrary javascript functions on objects, e.g., object.keys).

from specification point of view, analysis right under assumption particular implementation defines specific order of enumeration for-in statement:

if implementation defines specific order of enumeration for-in statement, same enumeration order must used in step 5 of algorithm.

see lastly sentence here.

so if implementation does not provide such specific order, for-in , object.keys may homecoming different things. well, in case 2 different for-ins may homecoming different things.

quite interesting, whole story reduces question if 2 for-ins give same results if object not changed. because, if not case, how test "the same" anyway?

in practice, true, imagine object rebuild internal construction dynamically, between for-in calls. instance, if property accessed often, implementation may restructure hash table access property more efficient. far can see, specification not prohibit that. , not-so-unreasonable.

so reply question is: no, there no guarantee according specification, still work in practice.

update

i think there's problem. defined, order of properties between members of prototype chain is? may "own" properties in right order, merged way it? instance, why kid properties first , parent's next?

javascript ecmascript-5

No comments:

Post a Comment