Modify String.prototype?

M

MartinRinehart

The FAQ shows a mod to String.prototype adding trim, trimRight and
trimLeft.

Flanagan states, "There is a strong argument against extending built-
in types with your own methods; if you do so, you are essentially
creating your own version of the JavaScript API." And he goes on to
say that this will confuse other programmers who may need to maintain/
extend your code.

Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable
properties, he says. However, Crockford breaks this rule regularly.

Best practice is?
 
L

Lasse Reichstein Nielsen

Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable
properties, he says. However, Crockford breaks this rule regularly.

Examples? It's not just to show what not to do?
Best practice is?

Don't.

/L
 
J

Jeremy J Starcher

The FAQ shows a mod to String.prototype adding trim, trimRight and
trimLeft.

Flanagan states, "There is a strong argument against extending built- in
types with your own methods; if you do so, you are essentially creating
your own version of the JavaScript API." And he goes on to say that this
will confuse other programmers who may need to maintain/ extend your
code.

There is a bit of truth to that. However, any coding feature may confuse
the next person who maintains your code. There is, as most things, a
balance.

It is my preference *not* to augment built-in object prototypes, but for
a different set of reasons. The next version of the spec may declare
string.{trim, trimRight, trimLeft}.
Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable
properties, he says. However, Crockford breaks this rule regularly.

I have never read Flanagan's book, but I have heard some rather negative
reviews about it on this group.

/Never/ is a strong word. I would say 'Don't do it unless you know what
you are doing' and 'Don't do it in any library code.'

Here is one of the big issues in augmenting Object.prototype:

for (var key in o) {
alert(key + "=>" + o[key]);
}

This will return properties of both 'o' and 'Object.prototype.' There is
a lot of code out there written in this style that depends upon 'o' only
having its own properties.

From what I remember, Crockford "filters" code in a method like this.
(Sorry if I'm slightly off, I don't have my copy of the spec here)

for (var key in o) {
if (o.hasOwnProperty(key)) {
alert(key + "=>" + o[key]);
}
}

Other people solve the problem by creating a /true/ associate array

/* UNTESTED CODE */
var o = {
'MyProps' : ["name", "age"],
"name" : "Jeremy J Starcher",
"age" : 0
};

for (var i = 0; i < o.MyProps.length; i++) {
key = o.MyProps;
alert(key + "=>" + o[key]);
}

This style has the added advantage that you pull data out of your object
in a particular order. Something that regular objects do NOT guarantee.
 
M

MartinRinehart

Lasse said:
Examples? It's not just to show what not to do?

"In Chapter 3 we saw that Object.prototype can be augmented.
Array.prototype can be augmented as well." p. 62

Chapter 3 example: beget() method that uses one object to create
another object (of the same "class").
 
D

dhtml

The FAQ shows a mod to String.prototype adding trim, trimRight and
trimLeft.

It should instead provide these as functions for the reasons provided by
Flanagan.
Flanagan states, "There is a strong argument against extending built-
in types with your own methods; if you do so, you are essentially
creating your own version of the JavaScript API." And he goes on to
say that this will confuse other programmers who may need to maintain/
extend your code.

We need an FAQ maintainer.
Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable

No disagreement there.
properties, he says. However, Crockford breaks this rule regularly.

Yes, he does.
Best practice is?

One place to modify built-ins is for adding support for features that
are feature-tested as buggy or missing.
 
D

dhtml

"In Chapter 3 we saw that Object.prototype can be augmented.
Array.prototype can be augmented as well." p. 62

Chapter 3 example: beget() method that uses one object to create
another object (of the same "class").

He has a way of getting around this with:-

for(var p in o) {
if(typeof o[p] !== "function") {

}
}

This will have filter out functions that have been added to
Object.prototype.

Modifying Object.prototype has some drawbacks. It requires other users
of API to use a non-standard technique, it will have different
Object.prototype in different frames. Changing what Object.prototype has
creates a dependency on the change and a relationship, so that all
objects now have that functionality.

A cleaner design approach is to resist the temptation to bugger
Object.prototype and create your own object type (or function) to
accomplish the task.

Garrett
 
J

Joost Diepenmaat

The FAQ shows a mod to String.prototype adding trim, trimRight and
trimLeft.

Flanagan states, "There is a strong argument against extending built-
in types with your own methods; if you do so, you are essentially
creating your own version of the JavaScript API."

This is IMHO essentially correct. The real question is how strong this
argument really is.
And he goes on to say that this will confuse other programmers who
may need to maintain/ extend your code.

I'd say that it *might* confuse other programmers. It also might
provide a lot of useful features for programmers not so easily
confused.
Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable
properties, he says.

I disagree. IMO, the main reason not to extend the built-in types and
especially Object is that it "breaks"

my o = { ... }
for (var p in o) {
// LOOP
}

in situations where programmers expect LOOP to only iterate over the
immediate properies (excluding the inherited properies) of o. In other
words; when you're using other people's code that may not expect this
behaviour.

This is exactly why Object.prototype.hasOwnProperty() exists, and
personally I think extending Object.prototype is just much too useful
to ignore.
However, Crockford breaks this rule regularly.

Crockford is not Flanagan.
Best practice is?

I don't know what best practices are. Do whatever you want, but be
careful.
 
R

Richard Cornford

Joost said:
This is IMHO essentially correct. The real question is how strong
this argument really is.

Flanagan has a confused notion of what "the javascript API" is to start
with; his book(s) still talk of "client-side" javascript long after that
concept has been abandoned. It would also be trivial to assert that the
creation of any global function was creating your own version of "the
javascript API", or that the purpose of exposing the built-in object
prototypes was so that they could be modified, and so modifying them
cannot be inherently wrong and should not be unexpected.
I'd say that it *might* confuse other programmers.

With the likelihood of its confusing other 'programmers' having a
relationship to how well they understand the nature of javascript. Where
a poor grasp of the subject is likely to result in very much else also
being confusing.
It also might provide a lot of useful features for programmers
not so easily confused.


I disagree. IMO, the main reason not to extend the built-in
types and especially Object is that it "breaks"

my o = { ... }
for (var p in o) {
// LOOP
}

in situations where programmers expect LOOP to only iterate
over the immediate properies (excluding the inherited properies)
of o. In other words; when you're using other people's code
that may not expect this behaviour.

This is exactly why Object.prototype.hasOwnProperty() exists,
and personally I think extending Object.prototype is just much
too useful to ignore.


Crockford is not Flanagan.


I don't know what best practices are. Do whatever you want, but
be careful.

It is very hard to see extending the prototypes for String, Number,
Boolean or Function as particularly problematic or undesirable. None of
those are likely to be subject to for-in iteration.

The real best practice is probably to take responsibility for what you
are doing an asses the trade-offs and their impacts. The issues mostly
come where there isn't the control to allow accurate judgements to be
made about the impact (i.e. in general purpose library code) where
caution is then advised, otherwise documentation stating the situation
within any given context (either that prototype extensions have been
used and for for-in needs to be handled cautiously, or that for-in has
been used incautiously on particular types so prototypes must not be
extended).

Richard.
 
J

Jorge

It is very hard to see extending the prototypes for String, Number,
Boolean or Function as particularly problematic or undesirable.

But try to avoid method names such as .clone() or .create()
or .defineProperty().

Use instead names as .myVeryOwnCloner() that are likely not to be ever
chosen to extend the language, when/if it gets ~"officially" extended.

--Jorge.
 
G

Gregor Kofler

(e-mail address removed) meinte:
The FAQ shows a mod to String.prototype adding trim, trimRight and
trimLeft.

Flanagan states, "There is a strong argument against extending built-
in types with your own methods;

I always thought, that's why you have the prototype chain, and the
opportunity to modify the prototype.
if you do so, you are essentially
creating your own version of the JavaScript API."

Doesn't compute.
And he goes on to
say that this will confuse other programmers who may need to maintain/
extend your code.

There are many more things that can confuse other programmers. Poor
documentation, convoluted scripts, odd method or property names ("$",
"$$", "_$",...), lambdas, etc. Augmented prototypes: not really.
Flanagan also states, "You must <i>never</i> add properties to
Object.prototype." Anything added to Object.prototype adds enumerable
properties to every object, including {}. {} shouldn't have enumerable
properties, he says. However, Crockford breaks this rule regularly.

Since you have hasOwnProperty() and advisably use it whenever you loop
with for ... in, I don't see the problem. But then I'm probably just a
staunch Crockford fan.
Best practice is?

Dunno. I use augmented prototypes and I happy with that. You could
always use a very special prefix for your extensions, to make it as
unique as possible (though I don't).

Gregor
 
T

Thomas 'PointedEars' Lahn

Jorge said:
But try to avoid method names such as .clone() or .create()
or .defineProperty().

Use instead names as .myVeryOwnCloner() that are likely not to be ever
chosen to extend the language, when/if it gets ~"officially" extended.

Your rationale, if it can be even called so, is unsound at best. Keywords
MUST be and future keywords SHOULD be avoided for identifiers; anything else
is just FUD.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Gregor said:
(e-mail address removed) meinte:

Since you have hasOwnProperty() and advisably use it whenever you loop
with for ... in, I don't see the problem. But then I'm probably just a
staunch Crockford fan.

As for Object.prototype.hasOwnProperty(), it should be noted that it is not
universally available, so augmenting Object.prototype carries with it the
necessity either to provide a method that is equivalent, or to accept that
the library will not be backwards-compatible (to JavaScript < 1.5, JScript <
5.5, ECMAScript < 3). Therefore, I have refactored library code that was
doing it.

However, I, too, see no problem augmenting prototype objects of objects that
are not likely to be subject to for-in iteration (such as String.prototype).
And a good library would provide an iterator method that helped its users
to work around the issue (mine does, in its local version).


PointedEars
 
R

RobG

I have never read Flanagan's book, but I have heard some rather negative
reviews about it on this group.

There have been negative comments about some of the things in it,
however it is still a good general reference provided you take its
advice with a grain of salt and do additional research.
 
J

Jorge

Your rationale, if it can be even called so, is unsound at best.  Keywords
MUST be and future keywords SHOULD be avoided for identifiers; anything else
is just FUD.

clap clap clap clap, BRAVO !

And how ** do you ** avoid using future keywords in the code written
by yours truly ?
 
O

optimistx

Jorge said:
clap clap clap clap, BRAVO !

And how ** do you ** avoid using future keywords in the code written
by yours truly ?

After googling as a stupid newbie , complete idiot and fool, etc, I found
FUD = female urination device.

So I think you can avoid future keywords with it: you simply put your
keys to the device and urinate, I think. If somebody knows better, pls
correct me.
 
J

John G Harris

clap clap clap clap, BRAVO !

And how ** do you ** avoid using future keywords in the code written
by yours truly ?

Here's an extract from the ECMAScript standard :

7.5.1 Reserved Words
Description
Reserved words cannot be used as identifiers.

Syntax
ReservedWord ::
Keyword
FutureReservedWord
NullLiteral
BooleanLiteral

...

7.5.3 Future Reserved Words
The following words are used as keywords in proposed extensions and
are therefore reserved to allow for the possibility of future
adoption of those extensions.

[Followed by a list of words such as class and static]

So the answer to your question is very simple. You look in ECMA 262 or
equivalent to see which words might be keywords in the future.

Also, it's not that they "should" be avoided; they "must" be avoided.

John
 
J

Jorge

clap clap clap clap, BRAVO !
And how ** do you ** avoid using future keywords in the code written
by yours truly ?

Here's an extract from the ECMAScript standard :

  7.5.1 Reserved Words
    Description
    Reserved words cannot be used as identifiers.

  Syntax
  ReservedWord ::
    Keyword
    FutureReservedWord
    NullLiteral
    BooleanLiteral

  ...

  7.5.3 Future Reserved Words
    The following words are used as keywords in proposed extensions and
    are therefore reserved to allow for the possibility of future
    adoption of those extensions.

[Followed by a list of words such as class and static]

So the answer to your question is very simple. You look in ECMA 262 or
equivalent to see which words might be keywords in the future.

Also, it's not that they "should" be avoided; they "must" be avoided.

Yes, but the (future) 3.1 extensions may not be in that list. What
happens with them ?
Will current code collide with 3.1 extensions, or will it just shadow
them ?
An Object.prototype.clone() method for example ?
 
J

John G Harris

Yes, but the (future) 3.1 extensions may not be in that list. What
happens with them ?

It's unlikely that a new keyword will appear as they've already listed
nearly all the C++ and Java keywords, including the more obscure ones.
E.g volatile and native.

Will current code collide with 3.1 extensions, or will it just shadow
them ?
An Object.prototype.clone() method for example ?

As you say, new global variables, global functions, and properties of
the built-in prototypes could have names used in existing code. Is this
really a problem ? Did anything bad happen when a browser first appeared
that had Object.prototype.isPrototypeOf ?

I suppose if a new property was read-only it could cause trouble. If the
Google website suddenly dropped dead would the browser company be sued
into bankruptcy ? I hope :)

John
 

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

No members online now.

Forum statistics

Threads
473,800
Messages
2,569,657
Members
45,417
Latest member
BonitaNile
Top