javascript - How does for loop index ascend the prototype chain? -
say have object person
so
var person = { firstname: 'default', lastname: 'default', getfullname: function() { return this.firstname + ' ' + this.lastname; } }
i make new object john
, set prototype of person
var john = { firstname: 'john', lastname: 'doe' } john.__proto__ = person;
if console.log
john
, see tree structure so
where see getfullname
embedded under __proto__
. here comes surprise
for (var prop in john) { console.log(prop) }
returns
even though getfullname
1 level deep, somehow, loop able find it.
now, compare to
var obj = {a: 1, b: {c:2, d: 3 }} (var prop in obj) {console.log(prop)}
which behaves expect, c
, d
not automagically found loop
so how in former case loop traversed deeper in tree dig embedded properties while in latter did not?
the for..in
loop iterate own enumerable properties, inherited enumerable properties. why seeing getfullname
in loop.
but in second case, lists properties of obj
, a
, b
(c
, d
properties of object b
).
this corresponding section language specification, for..in
, uses internal [[enumerate]]
slot.
the internal [[enumerate]]
slot used enumerate object passed gives enumerable properties of object. quoting section,
enumerating properties of target object includes enumerating properties of prototype, , prototype of prototype, , on, recursively;
since for..in
goes prototype chain recursively, able see objects defined in prototype, in case getfullname
.
if don't want getfullname
show during iteration, can define non-enumerable, this
var person = { firstname: 'default', lastname: 'default' }; object.defineproperty(person, 'getfullname', { value: function() { return this.firstname + ' ' + this.lastname; }, enumerable: false });
now when print keys, getfullname
not shown, not enumerable anymore.
note: using __proto__
should avoided, not part of ecmascript specifications. instead, should use object.setprototypeof
.
Comments
Post a Comment