On Apr 29, 2:08 pm, "Dmitry A. Soshnikov" <
[email protected]>
wrote:
(... ) And forgot about that only objects with
"Array" [[Class]] has overloaded internal methods related to arrays
stuff (15.4.5.1 in ES5).
Yeah. Object.create() returns an {}. To subclass [] we'd need an
Array.create(). I told this once to Brendan Eich @ es-discus, but
unfortunately I couldn't understand his too-complicated-for-me
response...
https://mail.mozilla.org/pipermail/es-discuss/2009-December/010425.html
And Brendan suggested [[Put]] to be delegable, but not determinate
only by some invariants (as it is now, and will), e.g. by [[Class]].
If [[Put]] would be delegable, then: own a.[[Put]] -> not found -> a.
[[Prototype]].[[Put]] - found and set "length" property accordingly.
In addition (as a variant) could be ability only to specify a
[[Class]] (it could be named as "type" e.g.) of the created object:
Object.created({
prototype: Array.prototype,
type: "Array",
// other properties
But it will be "too hard" (because require to be "prototype" and
"type" in this case a special properties, but not just normal). Also,
as I heard recently committee doesn't like (and won't standardize)
double-side-double-underscored __special__ properties, borrowed to ES
from Python. As actually __proto__, which is direct analogy of the
Python's __class__ and is for the same purpose.
Also, as was recently discussed @es-discuss list, all that new methods
which is now directly in "Object" constructor, but not in
"Object.prototype" led to that now we have three (!) syntactically
different approaches for the _same_ semantically entity - using
methods related with objects. The only reasonable thing is
stratification methods on "Meta" and "App" levels. But it is also very
debatable what should be treated as a "meta" and what is not (and
should ES do this the way as Java does). If will be interesting,
here's the complete discussion: <URL:
https://mail.mozilla.org/pipermail/es-discuss/2010-April/010908.html>
Yeah. I had seen that already.
var o = Object.freeze(
Object.seel(
Object.defineProperties(
Object.create(proto),
properties
)
)
);
var o = Object.create(proto)
.defineProperties(properties)
.seel()
.freeze();
that it is obvious that the first source even harder to read. And this
forced indention and repetition of Object.-Object.-Object. is just
ugly.
But that's a no-problem. They way they've done it you can build that
syntax yourself, if you wish:
(function (op) {
op.create= function (proto, p) {
return Object.create(proto, p ? p : undefined); };
op.defineProperties= function (p) {
Object.defineProperties(this, p); return this; };
op.seal= function () { Object.seal(this); return this; };
op.freeze= function () { Object.freeze(this); return this; };
})(Object.prototype);
var o=
({}).create(proto).defineProperties(properties).seal().freeze();
Yup, I also already showed m quickly solution for that (with aliases
for new methods (with renaming some of them) and some additional
useful "sugar"):
http://gist.github.com/367080/ .
Brendan himself pointed one of the reasons of why that methods are
directly in constructors (on examples with "array extras"), but not in
prototypes because -- comparing it with how Python's methods are
reflected. But he (at the same time) don't mention that in contrast
with JS, Python's properties/methods resolution chain is:
obj -> obj.__class__ -> ...
and in JS is:
obj -> obj.__proto__ -> ...
meanwhile constructor function after its main purpose (creating of
this object) isn't related with the "obj" at all.
In other words, in Python syntactic construction obj.method() is just
a "sugar" which automatically transforms to ObjClass.method(foo). But
in JS we should make aliases in two places - in constructor itself and
in the prototype - to make it convenient from the code reuse viewpoint
and at the same time having this methods generic, e.g. independent
from the [[Class]] of "this" value.
So, making aliases for all new "Object." methods seems to me
completely OK. At least, as I mention, I'll do it in all my own
projects.
Of course, from the other hand, it is "pain" if project uses several
3rd-party libs. Then it (being justified by committee and Brendan -
i.e. "avoid naming collisions and not to break the Web") should have
overloaded code always mentioning a long "namespace" before the needed
property/method. Yeah, that at the same time that now "with" is so
"evil" that should throw an exemption in "strict". Although, "with"
was (in correct using) is just a good analogy for "using namespace"
e.g.:
namespace("My.Widget")(function () { with (My.Widget) {
updateTree().repaint();
}});
Of course it's just an example (and maybe have some lacks), but -
nevertheless. To be fair, I myself do not use/used "with" on practice,
but think that there's nothing "evil" in it and taking into account
some circumstance I suppose, that I _could_ use it (yeah, function
expressions will have it scope chain, but, that's another question).
But, I guess all this is already another topic.
I don't think so. __proto__ is not a Good Thing™ due to some obscure
security reasons, and many of the seemingly odd-looking decisions wrt.
the new API, too, I heard.
Yeah, maybe (and concerning to web, I guess; else, Python is also just
a "big security hole"?), but from the code reuse viewpoint, it is (in
my opinion) more clear and elegant. Also, declarative definition style
also is more elegant.
Dmitry.