$H({}).get('__proto__') in Firefox =)

15 просмотров
Перейти к первому непрочитанному сообщению

Yaffle

не прочитано,
13 сент. 2009 г., 09:32:5313.09.2009
– Prototype: Core
var h = $H({});
h.set('__proto__','sadfdsf');
alert( typeof( h.get('__proto__') ));

Also try these:

alert(Object.toQueryString('hasOwnProperty=1'.toQueryParams()));
// hasOwnProperty=function%20()%20%7B%20%5Bnative%20code%5D
%20%7D&hasOwnProperty=1

May be "Object.prototype.hasOwnProperty.call(hash,key)" should be
used instead of 'key in hash' operator?

Yaffle

не прочитано,
13 сент. 2009 г., 10:13:4013.09.2009
– Prototype: Core
++IE dontEnum bug =)

var h = $H({});
h.set('toString',1);
alert(h.toJSON());

kangax

не прочитано,
13 сент. 2009 г., 12:20:4713.09.2009
– Prototype: Core
On Sep 13, 9:32 am, Yaffle <vic99...@yandex.ru> wrote:
> var h = $H({});
> h.set('__proto__','sadfdsf');
> alert( typeof( h.get('__proto__') ));

That's a known limitation, actually (although, probably not documented
anywhere). There's no key coercion in Prototype's Hash implementation,
which is why setting `__proto__` actually mutates [[Prototype]] of an
object that hash uses internally to store its values (btw, in Mozilla
`__proto__` can only be set once, contrary to, say, WebKit).

>
> Also try these:
>
> alert(Object.toQueryString('hasOwnProperty=1'.toQueryParams()));
> // hasOwnProperty=function%20()%20%7B%20%5Bnative%20code%5D
> %20%7D&hasOwnProperty=1
>
> May be  "Object.prototype.hasOwnProperty.call(hash,key)" should be
> used instead of 'key in hash' operator?

We didn't use `hasOwnProperty` since it was missing in Safari <2.0.4
(which we supported back then). Now that support for Safari 2.0.4 is
dropped, I still wouldn't use `hasOwnProperty`, as it's not as
reliable as it seems. For example, that same "__proto__" is being
reported as *own* property of an object in Mozilla and will still mess
things up. There could also be other non-standard magic properties
with unknown behavior. String coercion usually avoids this problem,
albeit in expense of slight performance decrease.

Also take a look at this related discussion -
http://groups.google.com/group/comp.lang.javascript/msg/f24941a8738be30d

--
kangax

Yaffle

не прочитано,
13 сент. 2009 г., 17:39:4713.09.2009
– Prototype: Core
You're right, `hasOwnProperty` can be useless, and
`propertyIsEnumerable` is useless becauseof dontEnum IE bug...
Why not to patch Hash to use some prefix for keys?

Tobie Langel

не прочитано,
13 сент. 2009 г., 18:38:1613.09.2009
– Prototype: Core
> Why not to patch Hash to use some prefix for keys?

That was my plan for 1.7, actually.

It fixes that issue and also avoids creating an extra, internal
object.

Good to see that we're on the same page, here.

Tobie

kangax

не прочитано,
13 сент. 2009 г., 19:56:4313.09.2009
– Prototype: Core
On Sep 13, 6:38 pm, Tobie Langel <tobie.lan...@gmail.com> wrote:
> > Why not to patch Hash to use some prefix for keys?
>
> That was my plan for 1.7, actually.
>
> It fixes that issue and also avoids creating an extra, internal
> object.

Sorry, I'm not following. How does prefixing a key avoid object
creation? We can't inject stuff directly onto a hash instance. We
still need an object for that.

[...]

--
kangax

Yaffle

не прочитано,
14 сент. 2009 г., 01:27:5314.09.2009
– Prototype: Core
What object creation?

javascript:alert(window.localStorage.__proto__)

Yaffle

не прочитано,
14 сент. 2009 г., 04:00:3214.09.2009
– Prototype: Core
var Hash = Class.create(Enumerable, (function() {

function specialClone(source,propertyFunc){
propertyFunc = propertyFunc || Prototype.K;
var destination = {};
for (var property in source) {
destination[propertyFunc(property)] = source[property];
}
return destination;
}


function initialize(object) {
this._object = (Object.isHash(object)? specialClone
(object._object,Prototype.K): specialClone(object,Hash.escape));
}

function _each(iterator) {
for (var key in this._object) {
var value = this._object[key], k = Hash.unescape(key), pair =
[k, value];
pair.key = k;
pair.value = value;
iterator(pair);
}
}

function set(key, value) {
key = Hash.escape(key);
return (this._object[key] = value);
}

function get(key) {
key = Hash.escape(key);
return this._object[key];
//if (this._object[key] !== Object.prototype[key]) {
// return this._object[key];
//}
}

function unset(key) {
key = Hash.escape(key);
var value = this._object[key];
delete this._object[key];
return value;
}

function toObject() {
return specialClone(this._object, Hash.unescape);
}

function keys() {
return this.pluck('key');
}

function values() {
return this.pluck('value');
}

function index(value) {
var match = this.detect(function(pair) {
return pair.value === value;
});
return match && match.key;
}

function merge(object) {
return this.clone().update(object);
}

function update(object) {
return new Hash(object).inject(this, function(result, pair) {
result.set(pair.key, pair.value);
return result;
});
}

function toQueryPair(key, value) {
if (Object.isUndefined(value)) return key;
return key + '=' + encodeURIComponent(String.interpret(value));
}

function toQueryString() {
return this.inject([], function(results, pair) {
var key = encodeURIComponent(pair.key), values = pair.value;

if (values && typeof values === 'object') {
if (Object.isArray(values)) {
return results.concat(values.map(toQueryPair.curry(key)));
}
} else {
results.push(toQueryPair(key, values));
}
return results;
}).join('&');
}

function inspect() {
return '#<Hash:{' + this.map(function(pair) {
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}

function toJSON() {
return Object.toJSON(this.toObject());
}

function clone() {
return new Hash(this);
}

return {
initialize: initialize,
_each: _each,
set: set,
get: get,
unset: unset,
toObject: toObject,
toTemplateReplacements: toObject,
keys: keys,
values: values,
index: index,
merge: merge,
update: update,
toQueryString: toQueryString,
inspect: inspect,
toJSON: toJSON,
clone: clone
};
}()));

Hash.from = $H;
Hash.escape = function(key){
return ' ' + key;
};
Hash.unescape = function(esc){
return esc.substr(1);
};

Sorry, i can't create git patch...

Yaffle

не прочитано,
14 сент. 2009 г., 05:31:0714.09.2009
– Prototype: Core
There is an issue with Hash#toObject method...

I think, Ajax.Base#parameters can be Hash instead of object to avoid
call to Hash#toObject...

Tobie Langel

не прочитано,
14 сент. 2009 г., 06:18:3314.09.2009
– Prototype: Core

> Sorry, I'm not following. How does prefixing a key avoid object
> creation? We can't inject stuff directly onto a hash instance. We
> still need an object for that.

Not necessarily. Though that might make some requests more expensive.

kangax

не прочитано,
14 сент. 2009 г., 08:45:5614.09.2009
– Prototype: Core
Sorry, I'm not following again :) What's not necessary? Which requests
will be more expensive?

--
kangax

Yaffle

не прочитано,
14 сент. 2009 г., 09:53:0714.09.2009
– Prototype: Core
> > Sorry, I'm not following again :) What's not necessary? Which requests
> > will be more expensive?

May be, for-in loop will iterate a little more ...

Yaffle

не прочитано,
21 сент. 2009 г., 16:40:0421.09.2009
– Prototype: Core
base2.js uses prefix for it's "Map" Class

kangax

не прочитано,
22 сент. 2009 г., 08:03:3822.09.2009
– Prototype: Core
On Sep 21, 4:40 pm, Yaffle <vic99...@yandex.ru> wrote:
> base2.js uses prefix for it's "Map" Class

Yes, but it uses a 1 char string - '#' - so the chance of collisions
is still high (imo).

[...]

--
kangax

Allen Madsen

не прочитано,
22 сент. 2009 г., 08:22:1822.09.2009
– prototy...@googlegroups.com
kangax, there are no collisions if everything is prefixed like Yaffle suggests.

Allen Madsen
http://www.allenmadsen.com

Yaffle

не прочитано,
23 сент. 2009 г., 13:23:1323.09.2009
– Prototype: Core
Ответить всем
Отправить сообщение автору
Переслать
0 новых сообщений