I just discovered that current iOS doesn't support ES2015 and Proxy
yet. I have a very small Proxy
object in my code, which I'm using to allow a function to be called upon access to myobject.non_formally_defined_property
, where I have no explicit property or property getter defined for the property in question.
How I can implement ES2015-compatible Proxy-like behavior? I want to continue to keep things the way they are. (A refactor would probably be ~20 lines of code, but the result would be a mess - I'm using this to implement initialization-time values for running configuration/state.)
After learning about defineProperty
I tried wiring that up to use the same function for all property accesses, but I'm very perplexed by the specific way it didn't work.
Specifically, I did this:
'use strict';
var arr = {
one: 1,
two: 2,
three: 3
}
var obj = {};
for (var item in arr) {
Object.defineProperty(obj, item, {
get: function (value) {
var local1 = item;
var local2 = (' ' + item).slice(1);
console.log('get: item=' + item + ' local1=' + local1 + " local2=" + local2);
},
});
}
obj.one;
<pre id=log></pre>
If you click Run Code, you'll see that console.log()
prints item=three local1=three local2=three
.
This is very confusing to me because
I don't think I'm overwriting the setter - I'm running
defineProperty
on the same object, yes, but on a differentitem
each time - so the closures should be different, right? - but I'm seeing three.The only way I can reason about that is that
That was the final loop value when the last closure (which overwrite the others?) was created, or
item
,local1
andlocal2
are somehow being fished out of the parent lexical scope, and of course they're allthree
from the final loop iteration. This doesn't make any sense though, because...
...
var
creates locally-scoped variables which are independent. To ensure thelocal*
variables were unique, Ilocal1
is a simple=
association, andlocal2
is a "deep copy" hack I grabbed from here just in case the copied string was linked by reference to the original.
So by every metric I can think of, the closures should be different, and I should be seeing the right variable show up. I'm very curious to understand why my approach doesn't work, but I'm especially interested to know how I can get getters/setters working!
Note that I want both get and set functionality, but I've only discussed getting here for simplicity.
I do not want to use any libraries. In my case this is because the JavaScript code is going into an HTML file I am emailing someone, I only want to email one file, and some pregenerated tables elsewhere in the HTML are already using 300KB+.