Augmenting Types

R

Ryan Chan

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};

String.method('trim', function() {
return this.replace(/^\s+|\s+$/g, '');
});


Is this a good thing in your opinion?
 
D

David Mark

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

....among other bad things.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

};

String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

});

Dear God. That's another step towards the abyss. :) First I find
out that YUI is crap and now this? Oh well, JSLint is nice anyway
(most of it).
Is this a good thing in your opinion?

No.
 
T

Thomas 'PointedEars' Lahn

Ryan said:
Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};

String.method('trim', function() {
return this.replace(/^\s+|\s+$/g, '');
});


Is this a good thing in your opinion?

No, because the call to String.method() would unconditionally overwrite the
property value in case there was already such a method. There needs to be
one in conforming implementations of ECMAScript Edition 5, so if you use
this exact pattern, you would in effect be replacing the faster built-in
method by a slower user-defined one. It is understandable that the book
does not consider this possibility as Edition 5 was published not before
2009-12. However, that does not excuse the lack of feature test before the
assignment or the lack of a property registry to work around unwanted
enumeration.

As to the question you wanted to ask: Such syntactic sugar can be a good
thing if done properly, and there is little wrong with it in this example.
However, if you augment built-in prototype objects you need to be aware
that all objects that have them in their prototype chain inherit those
properties, and that at least new prototype properties are enumerable (see
for-in iteration). Especially, if you augment the Object prototype object
the new properties will show up with for-in iteration over Array instances,
as their prototype chain is

[object Array] --> Array.prototype --> Object.prototype


PointedEars
 
G

Garrett Smith

Ryan said:
Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};

This is not a good thing.

The `method` method is not related to all Functions; only constructors.

It takes more time to comprehend that method than:-

MyConstructor.prototype.foo = fooFunc;

That method is unnecessary, not well named, adds overhead, adds clutter.

I criticized this part in another thread:
http://groups.google.com/group/comp...b741525ab6d/cd561210abc96faa#cd561210abc96faa
String.method('trim', function() {
return this.replace(/^\s+|\s+$/g, '');
});

No, it is not a good idea to replace a built-in method with a
hand-rolled version; not without good reason. In fact, without good
reason, that has some negative consequences.

String.prototype.trim is an ES5 standard method. It is implemented in
Tracemonkey (in Firefox).

A good reason for doing that would be, say, if an implementation did not
yet support the new method, or if it was shown to be buggy, but only
then after performing a /feature test/. The FAQ contains an example of
just that.

When Douglas wrote that, he probably did not consider the possibility
that String.prototype.trim would be added to the language.

The consequence of adding String.prototype.trim is that it replaces the
built-in String.prototype.trim with a user-defined version. That
user-defined version will not perform as fast as native code that it
replaced and will throw errors when used in a generic context.

| The following steps are taken:
| 1. Call CheckObjectCoercible passing the this value as its argument.
| 2. Let S be the result of calling ToString, giving it the this value
| as its argument.
| 3. Let T be a String value that is a copy of S with both leading and
| trailing white space removed. The definition of white space is the
| union of WhiteSpace and LineTerminator.
| 4. Return T.
|
| NOTE The trim function is intentionally generic; it does not require
| that its this value be a String object. Therefore, it can be
| transferred to other kinds of objects for use as a method.

The following are specified to work in ES5:

var trimFn = String.prototype.trim;
trimFn.call( window.getSelection() )
trimFn.call( new Error("You broke it.") );
trimFn.call( window.location );
trimFn.call( document.links[0] );

var range = document.createRange();
range.selectNode(document.body);

trimFn.call(range);

In Firefox, they correctly do convert the thisArt to string, as
specified by the standard.

However, when Douglas' method replaces that, it results in a TypeError.

By creating your own namespace, collisions like that can be avoided.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Ryan said:
Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};

This is not a good thing.

The `method` method is not related to all Functions; only constructors.

Non sequitur. All Function instances may be used as constructor.
It takes more time to comprehend that method than:-

MyConstructor.prototype.foo = fooFunc;

Only that this is not equivalent (note the `return'), and if feature-tests
were added as they should be, there would probably be the clutter that you
are talking of below, in the main code.
That method is unnecessary,
No.

not well named,

True, it would only qualify as `method' if it checked for method references
for the second argument, and the property name misses a verb (e.g.
setMethod).
adds overhead,

Any abstraction does. That is not a good reason for not doing it.
adds clutter.

Define: clutter.
By creating your own namespace, collisions like that can be avoided.

Whereas `namespace' should be understood as syntactic sugar created by
aggregation, not (yet) as a language feature. One should therefore be
aware that the less probability of name collision that this "namespacing"
provides comes with a performance penalty.


PointedEars
 
J

Jorge

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

};

String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

});

Is this a good thing in your opinion?

The -handy- ability to -miraculously- extend types on the fly -at
runtime- is another of these awesome JS's features that Brendan Eich
put there just for you not to use it. LOL.
 
D

David Mark

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

Is this a good thing in your opinion?

The -handy- ability to -miraculously- extend types on the fly -at
runtime- is another of these awesome JS's features that Brendan Eich
put there just for you not to use it. LOL.


Get a brain, Jorge. That's not what was asked.
 
D

Dmitry A. Soshnikov

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

};

String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

});

Is this a good thing in your opinion?

For do not repeat myself: <URL:
http://groups.google.ru/group/comp....64462/bbfb83eb82ef9b41?hl=en#bbfb83eb82ef9b41>

You should understand first the main issues related to the augmenting
of the built-ins. After that you can decide yourself is it a good
thing or not.

In general, if you understand what you're doing, it's not a bad
practice at all.

/ds
 
J

Jorge

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;
};
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');
});
Is this a good thing in your opinion?
The -handy- ability to -miraculously- extend types on the fly -at
runtime- is another of these awesome JS's features that Brendan Eich
put there just for you not to use it. LOL.

Get a brain, Jorge.  That's not what was asked.

Dear God. NO. That's another step towards the abyss. :)
 
D

David Mark

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

Is this a good thing in your opinion?

For do not repeat myself: <URL:http://groups.google.ru/group/comp.lang.javascript/browse_thread/thre...>

You should understand first the main issues related to the augmenting
of the built-ins. After that you can decide yourself is it a good
thing or not.

In general, if you understand what you're doing, it's not a bad
practice at all.

In a Web page, it's generally a terrible idea as scripts typically
have to co-exist with others. It pays to be defensive. ;) And that
"method" method is ridiculous.
 
D

David Mark

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;
};
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');
});
Is this a good thing in your opinion?
The -handy- ability to -miraculously- extend types on the fly -at
runtime- is another of these awesome JS's features that Brendan Eich
put there just for you not to use it. LOL.
Get a brain, Jorge.  That's not what was asked.

Dear God. NO. That's another step towards the abyss.  :)

Is that the "Jorge" re-mix? :(
 
D

Dmitry A. Soshnikov

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;
};
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');
});
Is this a good thing in your opinion?
You should understand first the main issues related to the augmenting
of the built-ins. After that you can decide yourself is it a good
thing or not.
In general, if you understand what you're doing, it's not a bad
practice at all.

terrible idea
terrible
terrible idea

Please, don't use demagogy, propaganda, and statement forms (novices
also read this and they can believe that propaganda is conclusive
true, but it's not always so) ;) Exchanging with meanings can't
operate with that. Or if you would like, please add "imHo" every time
you want to write so. It will be fairly, are you agree? ;)
In a Web page, it's generally a terrible idea as scripts typically
have to co-exist with others.

Well, yeah, I've mentioned - user should understand all the issues. If
he see the issues, he can decide do not do that. If not - he can do
that. It seems quite simple. Of cause, user should understand what
he's doing and why he's doing so.

For do not repeat myself, one more link: <URL:
http://groups.google.ru/group/comp....2af21b27a3b/560a9fb04339fdb8#f4ea783833329f83>

/ds
 
D

David Mark

On Jan 3, 10:50 am, "Dmitry A. Soshnikov" <[email protected]>
wrote:
Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;
};
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');
});
Is this a good thing in your opinion?
For do not repeat myself: <URL:http://groups.google.ru/group/comp.lang.javascript/browse_thread/thre...>
You should understand first the main issues related to the augmenting
of the built-ins. After that you can decide yourself is it a good
thing or not.
In general, if you understand what you're doing, it's not a bad
practice at all.
terrible idea
terrible
terrible idea

I didn't write this. (?!)
Please, don't use demagogy, propaganda, and statement forms (novices
also read this and they can believe that propaganda is conclusive
true, but it's not always so) ;)

Please don't forge quotes. :(
 
D

Dmitry A. Soshnikov

I didn't write this. (?!)




Please don't forge quotes.  :(

That was specially to show that I see your speaking manner and free
you from trying to do that (you can stop trying it, I've already
"appreciate" it) ;) You know, it also can be so, when person don't
completely understand what he's talking about, he can use some
demagogy and statement form for to show to the other readers, that
he's speaking with the sure tone. Sure better to use some strong words
such as "terrible" and so on. It can be treated by those who don't
completely understand the subject, that that person speaks (always)
truly.

You statement with the sure tone that it's "terrible idea", although,
it's just your (humble.) opinion. Will you mind?

P.S.: Though, all this does not cancel really awful and terrible
ideas ;) I also can use this words when the idea is really terrible.

/ds
 
D

Dmitry A. Soshnikov

And that
"method" method is ridiculous.

I didn't touch the concrete method(s) of Crockford, I don't mind. I
was talking about the general theory of the augmenting of the built-
ins.

But yep, the "method" method is ridiculous, I agree ;)

/ds
 
J

John G Harris

On 3 0

Please, don't use demagogy, propaganda, and
<snip>

Please don't give such misleading quotes. They are a form of demagogy
and propaganda.


You could have quoted like this :

<your agreement about 'co-exist'>

John
 
D

Dmitry A. Soshnikov

  <snip>

Please don't give such misleading quotes. They are a form of demagogy
and propaganda.

Please, pay attention that I used it specially (as a kind of irony) to
show, how it looks. For what reason, I should give in on provocation
and accept such rules when one person statements his humble opinion
with sure tone "That's wrong. That's terrible." (this person tries to
take the main role and to take the dialog in his hands) and the other
one should prove why it's not so (this person is kind of that
justifies). It's direct demagogy which I see and don't wanna accept.
That's it. Objections?
You could have quoted like this :


  <your complaint about 'terrible'>

I know that, thanks.
  <your agreement about 'co-exist'>

I also know that, thanks.

/ds
 
J

Jorge

(...)

<your agreement about 'co-exist'>

"agreement" ?

The typicality of that hypothetical coexistence is very debatable.
And, in any case, "others" is !== "unknown scripts". Do you allow
"unknown" code to run in your page ? Does any of these -hypothetical-
cohabitant scripts break anything ? And if they do, why ? Don't their
authors know about .hasOwnProperty() existence and purpose ? Is that
reason enough to ditch .prototype inheritance altogether ? The answer,
in general, is NOT yes. The answer, in general, is of course NOT.
 
D

David Mark

"agreement" ?

The typicality of that hypothetical coexistence is very debatable.

That's ludicrous. How many Web pages use a single script from a
single author (well, I know of a few at least). :)
And, in any case, "others" is !== "unknown scripts". Do you allow
"unknown" code to run in your page ?

Me? Not typically, no. Am I typical?
Does any of these -hypothetical-
cohabitant scripts break anything ?

You are babbling.
And if they do, why ? Don't their
authors know about .hasOwnProperty() existence and purpose ?

You truly are a student of Crockford. For about the millionth time,
that method doesn't work in "ancient" browsers like Safari 2. I see
it used without proper feature detection and wonder if the authors
realize their scripts will suddenly halt at that spot. Does that seem
a sound degradation strategy to you?

And of all the miserable JS libraries out there, how many actually
filter for-in loops in any form?
Is that
reason enough to ditch .prototype inheritance altogether ?

Does it seem to you that I've "ditched" ".prototype inheritance".
Look again.
The answer,
in general, is NOT yes.
The answer, in general, is of course NOT.

Lucid as always. :)
 
J

JR

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.

Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;

};

I've read the book too, but in my version (2008 in Portuguese) that
function is slightly different, with one very important feature test:

Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
// I didn't see this return this mentioned above.
}
};

And there is a precautionary note about augmenting types, specially
when the page utilizes different libraries / codes.
I also have not read Douglas recommending this type of thing, but
saying that it was possible to do so, arguing that it could make
improvements in the expressiveness of JavaScript.

However, I must admit that that 'part' of the book is confusing and
can mislead readers about the matter (augmenting types); in other
words, a reader might unwittingly adopt the book's example as a good
practice, what would be a temerity.
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');

});

Is this a good thing in your opinion?

No, it isn't, even in case you know exactly what you're doing.
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top