From: Thomas 'PointedEars' Lahn on
John G Harris wrote:

> Thomas 'PointedEars' Lahn wrote:
>> John G Harris wrote:
>>> Javascript is more flexible.
>> There is no "Javascript", [...]
>
> Yes there is, but only at the beginning of sentences (in English).

Nonsense. Please get yourself informed:

<http://PointedEars.de/es-matrix>


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
From: kangax on
On 1/16/10 2:45 PM, Asen Bozhilov wrote:
> Dmitry A. Soshnikov wrote:
>
>> It depends. For some, code with some builder-wrapper, is more simple
>> than to describe first constructor itself, than add methods
>> (especially if you have already `methods' method to add methods).
>>
>> It's like e.g. in Ruby, where classes are just objects of class
>> `Class'. Regarding to ECMAScript wrapper for chaining prototypes it
>> can look similar.
>
> Thank for all of your responses and suggestions. That is my final
> solutions.
>
> var Class = (function()
> {
> var F = function(){},
> Base = function(){};
> Base.prototype = {
> constructor : Base,
> baseMethod : function(name)
> {
> var proto = this._proto,
> parent = proto._parent;
> delete proto._parent;
> delete proto._proto;
> var result = parent[name].apply(this, Array.prototype.slice.call
> (arguments, 1));
> proto._parent = parent;
> proto._proto = proto;
> return result;
> },
>
> base : function()
> {
> var args = [arguments.callee.caller._name];

You do remember that `arguments.callee` throws in ES5 strict mode, don't
you? ;)

> return this.baseMethod.apply(this, args.concat.apply(args,
> arguments));

AFAIR, `push` is usually faster.

> },
>
> addProperties : function(o)
> {
> for (var i in o)
> {
> if (o.hasOwnProperty(i))

Would be safer to do:

if (Object.prototype.hasOwnProperty.call(o, i))

> {
> var property = o[i];
> if (typeof property == 'function')

Will match regex in some versions of WebKit (where `typeof /(?:)/ ==
"function"`)

> {
> property._name = i;
> }
> this[i] = property;
> }
> }
>
> var jscript = ['valueOf', 'toString', 'constructor'];

Maybe `dontEnum` (or `dontEnumBuggy`, or `dontEnumBuggyProps`) would be
a more descriptive name here. Also, why only 3 out of 7?

And there's really no need to perform all this DontEnum boilerplate in
conforming environments (that's what we did in Prototype.js
inefficiently, for a long time).

Better to test once, then fork accordingly. E.g.:

var IS_DONTENUM_BUGGY = true;
for (var i in {toString:1}) {
IS_DONTENUM_BUGGY = false;
}

....

if (IS_DONTENUM_BUGGY) {
/* do the workaround */
}

> for (i = 0; i< jscript.length; i++)
> {
> property = jscript[i];
> if (o.hasOwnProperty(property))

Same as above regarding `hasOwnProperty`.

> {
> this[property] = o[property];
> o[property]._name = property;
> }
> }
> }
> };
>
> return function(properties)
> {
> var extend = properties.extend || Base,
> constructor = properties.constructor;
> F.prototype = extend.prototype;
> var p = constructor.prototype = new F();
> p._proto = p;
> p._parent = extend.prototype;
>
> delete properties.extend;
> p.addProperties(properties);
>
> return constructor;
> };
> })();
>

[snip example]

--
kangax
From: Asen Bozhilov on
kangax wrote:

> You do remember that `arguments.callee` throws in ES5 strict mode, don't
> you? ;)

Of course i know that. That is the reason to support two ways with
`base' and more compatible `baseMethod'.

> AFAIR, `push` is usually faster.

I'll test that, and if you are right I'll be change.

> Would be safer to do:
> if (Object.prototype.hasOwnProperty.call(o, i))

Thanks. Here you are definitely right. I mix to independent things. If
someone one to define own `hasOwnProperty' method, i will use in part
of my code, where i expect different behavior.

> Maybe `dontEnum` (or `dontEnumBuggy`, or `dontEnumBuggyProps`) would be
> a more descriptive name here.

Yes, and i don't like this part of my code. Also need to optimized,
and I'll do it.

> Also, why only 3 out of 7?

Which others four? I don't find good article about {DontEnum} bug in
JScript implementation. I know only for that three user defined
properties in native objects. Can you give link or example?
Thanks.
From: Thomas 'PointedEars' Lahn on
kangax wrote:

> Asen Bozhilov wrote:
>> Dmitry A. Soshnikov wrote:
>>> It depends. For some, code with some builder-wrapper, is more simple
>>> than to describe first constructor itself, than add methods
>>> (especially if you have already `methods' method to add methods).
>>>
>>> It's like e.g. in Ruby, where classes are just objects of class
>>> `Class'. Regarding to ECMAScript wrapper for chaining prototypes it
>>> can look similar.
>>
>> Thank for all of your responses and suggestions. That is my final
>> solutions.
>>
>> var Class = (function()
>> {
>> var F = function(){},
>> Base = function(){};
>> Base.prototype = {
>> constructor : Base,
>> baseMethod : function(name)
>> {
>> var proto = this._proto,
>> parent = proto._parent;
>> delete proto._parent;
>> delete proto._proto;
>> var result = parent[name].apply(this, Array.prototype.slice.call
>> (arguments, 1));
>> proto._parent = parent;
>> proto._proto = proto;
>> return result;
>> },
>>
>> base : function()
>> {
>> var args = [arguments.callee.caller._name];
>
> You do remember that `arguments.callee` throws in ES5 strict mode, don't
> you? ;)

Nobody (but you) cares about "ES5 strict mode".

>> return this.baseMethod.apply(this, args.concat.apply(args,
>> arguments));
>
> AFAIR, `push` is usually faster.

It is not equivalent, though.

>> },
>>
>> addProperties : function(o)
>> {
>> for (var i in o)
>> {
>> if (o.hasOwnProperty(i))
>
> Would be safer to do:
>
> if (Object.prototype.hasOwnProperty.call(o, i))

How so? All built-in objects need to implement hasOwnProperty() as they
have Object.prototype in their prototype chain, and nobody sane would pass
a host object here.

>> {
>> var property = o[i];
>> if (typeof property == 'function')
>
> Will match regex in some versions of WebKit (where `typeof /(?:)/ ==
> "function"`)

So what?

>> {
>> property._name = i;
>> }
>> this[i] = property;
>> }
>> }
>>
>> var jscript = ['valueOf', 'toString', 'constructor'];
>
> Maybe `dontEnum` (or `dontEnumBuggy`, or `dontEnumBuggyProps`) would be
> a more descriptive name here. Also, why only 3 out of 7?
>
> And there's really no need to perform all this DontEnum boilerplate in
> conforming environments (that's what we did in Prototype.js
> inefficiently, for a long time).

You do a lot more things wrong in Prototype.js than just this.

> Better to test once, then fork accordingly. E.g.:

Better to forget the whole stupid idea of a `Class' factory.


PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300dec7(a)news.demon.co.uk>
From: Asen Bozhilov on
kangax wrote:

> Better to test once, then fork accordingly. E.g.:
>
> var IS_DONTENUM_BUGGY = true;
> for (var i in {toString:1}) {
>    IS_DONTENUM_BUGGY = false;
>
> }

I prefer to use `propertyIsEnumerable':

var IS_DONTENUM_BUGGY = {'toString' : true}.propertyIsEnumerable
('toString'); //JScript false

Of course, i know disadvantages of `propertyIsEnumerable', because
Safari 2 isn't supported and JScript < 5.5 too.