ECMA-262-5 in detail. Chapter 1. Properties and Property Descriptors.

  • Thread starter Dmitry A. Soshnikov
  • Start date
R

Ry Nohryb

OK, the new series has just begun.

"ECMA-262-5 in detail. Chapter 1. Properties and Property
Descriptors." (...)

"Using such approach you at last can create inherited from
Array.prototype “class” with all functionality of normal arrays
including overloaded [[Get]] and [[Put]] internal methods which handle
e.g. length property."

There's still NO WAY to subclass Array in ES (neither 3 nor 5) : your
"foo" Array subclass is broken:

foo
--> [1,2,3]
foo.length
--> 3
foo[22]= 27
foo.length
--> 3

You'd be better off doing this, ISTM:

(foo= []).sum= arraySum;

For the internal get and put are not in your foo. The ONLY way to
subclass Array is using the non-standard __proto__ to insert one (or
more than one to subclass a subclass) intermediate object(s) in the
prototype chain of a true [] :

var foo= [];
foo.__proto__= { foo: "FOO" };
foo.__proto__.__proto__= Array.prototype;

foo instanceof Array
--> true

foo.foo
--> "FOO"

foo.length
--> 0

foo.push(66)
--> 1

foo[3]= 66
foo.length
--> 4

foo
--> [66, undefined, undefined, 66]

foo.length= 0
foo
--> []
 
D

Dmitry A. Soshnikov

OK, the new series has just begun.
"ECMA-262-5 in detail. Chapter 1. Properties and Property
Descriptors." (...)

"Using such approach you at last can create inherited from
Array.prototype “class” with all functionality of normal arrays
including overloaded [[Get]] and [[Put]] internal methods which handle
e.g. length property."

There's still NO WAY to subclass Array in ES (neither 3 nor 5) : your
"foo" Array subclass is broken:

foo
--> [1,2,3]
foo.length
--> 3
foo[22]= 27
foo.length
--> 3

You'd be better off doing this, ISTM:

(foo= []).sum= arraySum;

For the internal get and put are not in your foo. The ONLY way to
subclass Array is using the non-standard __proto__ to insert one (or
more than one to subclass a subclass) intermediate object(s) in the
prototype chain of a true [] :

var foo= [];
foo.__proto__= { foo: "FOO" };
foo.__proto__.__proto__= Array.prototype;

foo instanceof Array
--> true

foo.foo
--> "FOO"

foo.length
--> 0

foo.push(66)
--> 1

foo[3]= 66
foo.length
--> 4

foo
--> [66, undefined, undefined, 66]

foo.length= 0
foo
--> []

Absolutely correct. I knew that for ES3 of course, but have hastened
with it for ES5. Just thought which more interesting example to use
and used that. And forgot about that only objects with
"Array" [[Class]] has overloaded internal methods related to arrays
stuff (15.4.5.1 in ES5).

Thanks, fixed. I also added your example.

Dmitry.
 
R

Ry Nohryb

Thanks, fixed. I also added your example.

You're welcome Dmitry.

"And unfortunately, in contrast with __proto__ extension of some ES3
implementation, ES5 does not provide ability for setting an object’s
prototype."

I find this phrase a bit nonsensical. The __proto__ wasn't part of ES
before (ES3) and still isn't (ES5). It was provided by some
implementations, and it's still being provided by these
implementations. AFAIK.
 
D

Dmitry A. Soshnikov

"And unfortunately, in contrast with __proto__ extension of some ES3
implementation, ES5 does not provide ability for setting an object’s
prototype."

I find this phrase a bit nonsensical. The __proto__ wasn't part of ES
before (ES3) and still isn't (ES5). It was provided by some
implementations, and it's still being provided by these
implementations. AFAIK.

Actually I meant the same. That for the word "extension" is - which
means it isn't standard, but an own extension of _some_
implementations.

Yes, it's still available in some implementations which already has
almost complete implementation of ES5 features.

So, I added "non-standard" word, maybe so it will be more clear:

"in contrast with non-standard __proto__ extension of some ES3
implementations"

Dmitry.
 
D

Dmitry A. Soshnikov

(... ) 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

Yep, I see.

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>

I already mentioned:

var o = Object.freeze(
Object.seel(
Object.defineProperties(
Object.create(proto),
properties
)
)
);

And:

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.

The same could be for:

var o = Object.create(SomePrototypeObject, {
...
});

And:

var o = {
__proto__: SomePrototypeObject,
...
};

The second source seems lighter, but, repeat, the committee doesn't
like __special__ properties. But, everything can be changed.

Dmitry.
 
R

Ry Nohryb

Actually I meant the same. That for the word "extension" is - which
means it isn't standard, but an own extension of _some_
implementations.

Yes, it's still available in some implementations which already has
almost complete implementation of ES5 features.

So, I added "non-standard" word, maybe so it will be more clear:

"in contrast with non-standard __proto__ extension of some ES3
implementations"

If it's non-standard it's not "in contrast" with ES5...
 
R

Ry Nohryb

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... :)

Yep, I see.

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.
I already mentioned:

var o = Object.freeze(
   Object.seel(
     Object.defineProperties(
       Object.create(proto),
       properties
     )
   )
);

And:

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();

The same could be for:

var o = Object.create(SomePrototypeObject, {
  ...

});

And:

var o = {
  __proto__: SomePrototypeObject,
  ...

};

The second source seems lighter, but, repeat, the committee doesn't
like __special__ properties. But, everything can be changed.

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.
 
D

Dmitry A. Soshnikov

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
Yep, I see.
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.


I already mentioned:
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.
 
D

Dr J R Stockton

In comp.lang.javascript message <f8544770-3eab-4a85-ac2f-3116c138e5c7@z3
0g2000yqz.googlegroups.com>, Thu, 29 Apr 2010 02:27:10, Dmitry A.
Soshnikov said:
OK, the new series has just begun.

"ECMA-262-5 in detail. Chapter 1. Properties and Property
Descriptors."

http://dmitrysoshnikov.com/ecmascript/es5-chapter-1-properties-and-
property-descriptors/

It isn't already a translation, but the original. But, nevertheless,
additions/corrections -- technical and in English are welcome.

Web http://validator.w3.org/ does not much like the page.

The CSS file includes :-

body {
background-color: #F9F9F9;/*#F1F3E9;*/
font: 12px Verdana, Arial, 'Helvetica', sans-serif;
padding: 0;
}


Fixing the font size is bad; leave it at 100% of reader's preference.
Verdana is not good, because it is "big for its size" and if it is
present in your system and absent on a reader's system the reader will
be shown a smaller-looking font.

Try removing everything not needed from the CSS; make all text sizes
percentages, and give other text-related sizes in ex or em units.

code ... "font: 9pt monospace, Verdana, Arial, 'Helvetica', sans-serif;"
- is it not the case that all systems have monospace, as it is generic?


If writing one's own set of pages, I suggest that one should never use a
CSS file from "outside". Write a new one, and copy into it only what
one knows, and proves, is good. And validate it.


On font size : I have here two networked PCs, and the screen sizes are
almost identical in inches (and presumably in centimetres). But the
desktop one has a 1280*1024 CRT screen, and the laptop has a 1024*768
LCD screen, naturally with sharper pixels. Your font size is noticeably
better on the laptop.
 

Ask a Question

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.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,816
Latest member
nipsseyhussle

Latest Threads

Top