L
Lasse Reichstein Nielsen
Richard Cornford said:I don't see any way of acquiring a reference to an object with less
than one object on its prototype chain.
Object.prototype
But apart from that, no.
/L
Richard Cornford said:I don't see any way of acquiring a reference to an object with less
than one object on its prototype chain.
Lasse said:Object.prototype
But apart from that, no.
Lasse said:It works fine for that. The problem is that it doesn't start out empty,
but wnything you put in, you get out again fine.
^^^^^^^^^^^^^^^^^^^^^^Richard did. He suggested a single space IIRC.
Ok, an associative array implementation that isn't fooled by standard ^^^^^^^^^^^^^^^^^^^^^^^^
or non-standard values:
---
function Map() {
this.map = {};
}
Map.Value = function Value(v) {
this.value = v;
}
Map.prototype.containsKey = function containsKey(k) {
return (this.map[k]) instanceof Map.Value;
^^^^^^^^^^^^^^^^^^^^^^}
Map.prototype.put = function put(k,v) {
this.map[k] = new Map.Value(v);
};
Map.prototype.get = function get(k) {
var v = this.map[k];
if (v instanceof Map.Value) {
return v.value;
}
};
Map.prototype.remove = function remove(k) {
delete this.map[k]
};
Thomas said:^^^^^^^^^^^^^^^^^^^^^^Lasse said:Map.prototype.containsKey = function containsKey(k) {
return (this.map[k]) instanceof Map.Value; [...]
}
Map.prototype.put = function put(k,v) {
this.map[k] = new Map.Value(v);
};
Map.prototype.get = function get(k) {
var v = this.map[k];
if (v instanceof Map.Value) {
Would it not be wise to use this.contains(v) here?
Thomas 'PointedEars' Lahn said:^^^^^^^^^^^^^^^^^^^^^^
What is this supposed to mean?
Map.prototype.remove = function remove(k) {
delete this.map[k]
};
Your implementation is still missing the point: Objects have built-in
properties that are often not enumerable but could still be overwritten
(including methods!)
and thus assignment to objectReference[k] (here: this.map[k]) must
not be allowed for those values of k.
Encapsulating the value in another (prototyped) object (twice) does
not really help here, and if the used object contains _only_ a value
property this approach is merely a waste of memory.
Only a suitable transparent modification of the passed property name
(suffix, prefix, infix; while one the former to should be used) will
solve that problem.
Lasse said:This solves it for correct ECMA262 implementations.
Modifying the property name blindly will not be absolutely safe, since
you might hit another preexisting property name with the modified name
as well (who knows, maybe some day, an ECMAScript impelentation will
have a hidden method called " hiddenMethod " on Object prototype).
Lasse said:Hmm ... should be: fooled by existing standard or non-standard
properties.
Map.prototype.remove = function remove(k) {
delete this.map[k]
};
Your implementation is still missing the point: Objects have built-in
properties that are often not enumerable but could still be overwritten
(including methods!)
Absolutely. I'm depending on them being overwritable.
and thus assignment to objectReference[k] (here: this.map[k]) must
not be allowed for those values of k.
Yes it must. The object used as a map here (this.map) is *only* used
for this purpose. Any property that it has inherited should be ignore,
and can safely be overwritten. That is, *if* they can be overwritten.
If the properties are "magic", like, e.g., innerHTML on DOM nodes, or
"length" on Arrays, then even overwriting is a problem.
However, that would be a violation of ECMA 262, since an object is
created using "new Constructor", where "Constructor" is a user defined
function, can not be a host object.
What you might be thinking of, is that deleting existing properties
should not be allowed,
which is true (no "delete Object.prototype.toString").
No, the point of wrapping in an instance of Map.Value is that no
preexisting property is an instance of Map.Value.
That allows us to distinguish properties that we put in the map from those
already there, no matter what type they might be (including objects or
arrays).
This solves it for correct ECMA262 implementations.
Thomas 'PointedEars' Lahn said:But some properties are read-only.
If so, you would overlay core properties leading to unexpected behavior
because the respective prototype property will not be accessed anymore.
And if not, you would have saved nothing in your "hash table". That
does not sound like a (reasonable/viable) solution.
This is not about host objects, it is about core properties *every*
object has.
You would effectively overlay Object.prototype.toString if you would try
to add a "toString" hash table entry and cause to property cease to work
as supposed.
Or consider a "valueOf" hash table entry. Or "constructor".
Or ...
Even your Map and Map.Value instances have preexisting properties
inherited from Object. They may not be enumerable but they still
exist. There is no, I repeat, *no* object that has no "preexisting
properties".
I won't debate that you can distinguish between added and built-in
properties and I did not. The point is that your implementation does
not prevent overlaying or overwriting built-in properties.
You control the read, but not the write process (yet).
No, it does not, because of
,-[ECMA 262 Edition 3, 2000-03-24]
|
| 2 Conformance
And unfortunately(?), we are not living in a perfect standardized world.
Implementations make use of the opportunity described above, there is
escape(), unescape(), __proto__ and *much* more out there.
Exactly ECMA-262 and the prototype chain presents the reason why your
hash table implementation "as is" is flawed.
Lasse said:Thomas 'PointedEars' Lahn said:If so, you would overlay core properties leading to unexpected behavior
because the respective prototype property will not be accessed anymore.
No unexpected behavior will happen, as long as the object is only used
to look up properties in. No "core property" affects how [[Get]] and
[[Put]] works.
Unexpected behavior might happen if I overwrite the "toString"
property *and* tries to convert the object to a string, but I never do
that.
Not understood.
This is not about host objects, it is about core properties *every*
object has.
That every object's *prototype* has. The object itself has no
properties.
Doing
new Object()
creates a new native ECMAScript object. It has no visible properties
itself, only the ones inherited from its [[Prototype]], Object.prototype.
ACK
^^^^^You control the read, but not the write process (yet).
Sure I do, unless the implementation is pathologically flawed.
As long as a *new* object has no properties itself (not counting the ones
inherited from its prototype) that are read-only or don't-delete, then
it will work.
An implementation that makes a new object have a read-only or
don't-delete property that cannot be overwritten is asking for
trouble. Imagine
var x = new Object();
x.xyzzy = 42; // bang! "xyzzy" is read-only. Not a good idea!
No, the prototype chain guarantees that the read-only or don't-delete
properties of the prototype can be overwritten in the inheriting
object.
Thomas 'PointedEars' Lahn said:I meant that you do not check if there is a prototype
property (yet) before over*writing*/overlaying it.
Hmmm. If you overlay `prototype', you would destroy
(the possibility of) inheritance, would you not?
....
Not a good idea for Object objects. Perfectly reasonable for others.
ACK, but I would refrain from overlaying prototype properties anyway here.
Lasse said:Thomas 'PointedEars' Lahn said:I meant that you do not check if there is a prototype
property (yet) before over*writing*/overlaying it.
Correct. It shouldn't matter, though.
Hmmm.
Hmmm. If you overlay `prototype', you would destroy
(the possibility of) inheritance, would you not?
No. The "prototype" property is only relevant on function objects, and
the map object ("this.map") is just a normal object. [...]
Out of curiosity: Why?
Thomas 'PointedEars' Lahn said:I meant `constructor' (and the like). Can you think of
overlaying one of them to interfere with normal operation
(toString() aside, which is obvious)?
AFAIS it makes the implementation less flexible and thus restricts
the freedom of the users to apply it to their needs, effectively
making it less attractive to them.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.