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

enter image description here

where see getfullname embedded under __proto__. here comes surprise

for (var prop in john) {   console.log(prop) } 

returns

enter image description here

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

enter image description here

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

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

java.lang.NoClassDefFoundError When Creating New Android Project -

Decoding a Python 2 `tempfile` with python-future -