Augmenting Types

T

Thomas 'PointedEars' Lahn

kangax said:
Thomas said:
kangax wrote:
There is *nothing* in the Specification that says that Function
instances are not [[Construct]]able by default. In fact, function
instances/objects do have by default an internal [[Construct]]
property. (13.2)

Aren't we talking about built-in functions? What do Function instances
have to do with this?

If you had cared to read the definitions I quoted ...
How is this a proof?

`Object' is a built-in function.
"...unless otherwise specified in the description of a particular
function" clause (from what you cited above) allows this.

Irrelevant, that was not in the original (Garrett's) statement.
Apparently your logic module is borken after all.


PointedEars
 
E

Eric Bednarz

David Mark said:
You truly are a student of Crockford. For about the millionth time,
that method doesn't work in "ancient" browsers like Safari 2.

It works in Safari 2.04; I would expect that people who are stuck with
OS X 10.4 would still run system updates.
I see
it used without proper feature detection

Booo! :)
 
T

Thomas 'PointedEars' Lahn

David said:
And I think it bears pointing out that there is no recovery from
[an "automation server can't create object ..."] exception.

Wrong, try-catch can handle this.


PointedEars
 
J

Jorge

The guy asked our opinion. Mine was stated: I'm against type
augmentation although I know it's possible and can increase
expressiveness of JS. That's just an opinion and I can't see how being
prudent would be a step towards the abyss? I believe in "If it isn't
broken, don't fix it.", and "If something can go wrong, it will."

That user defined properties -inherited or not- are enumerable isn't
something to be afraid of, and String.prototype.trim() is a good
example of handiness that can't break anything. If it broke a certain
script, the culprit would be that script's author's ignorance, but
instead you and Mark are mistakenly pointing at a nice feature of the
language as the culprit and advocating to mutilate it... ¿?
 
T

Thomas 'PointedEars' Lahn

Because your opinion expressed above is not based on prudence but on
irrational fear instead. It goes without saying that if one knows exactly
what they are doing, they must also be aware of the side-effects.

In a way, a trim() prototype method present in one implementation and not
in another is something that is borken in the latter because it would
require a different approach in the main code.

On a second thought, one might also want to program non-interoperabilities
out of the trim() implementation which is a goal worth pursuing despite the
reduced efficiency of the user-defined code.

Fear is a bad advisor.
That user defined properties -inherited or not- are enumerable isn't
something to be afraid of,

But to be kept in mind.
and String.prototype.trim() is a good example of handiness that can't
break anything.

That is, if it is done properly, contrary to the example. For it is rather
unlikely that anyone would plainly for-in iterate over String instances or
values without general property detection or side-effects in mind.
If it broke a certain script, the culprit would be that script's
author's ignorance, but instead you and Mark are mistakenly pointing
at a nice feature of the language as the culprit and advocating to
mutilate it... ¿?

ACK


PointedEars
 
J

JR

Because your opinion expressed above is not based on prudence but on
irrational fear instead.  It goes without saying that if one knows exactly
what they are doing, they must also be aware of the side-effects.

No, it's prudence against the many that *think* they know what they're
doing.

In a way, a trim() prototype method present in one implementation and not
in another is something that is borken in the latter because it would
require a different approach in the main code.

Why this insistence on the term 'borken'? Why not writing broken?

On a second thought, one might also want to program non-interoperabilities
out of the trim() implementation which is a goal worth pursuing despite the
reduced efficiency of the user-defined code.


Fear is a bad advisor.

The cemetery is full of fearless men.
But to be kept in mind.


That is, if it is done properly, contrary to the example.  For it is rather
unlikely that anyone would plainly for-in iterate over String instances or
values without general property detection or side-effects in mind.


ACK

No, you are mistaken. Read again: I did not advise anyone to
'mutilate' JS, instead I commented (as an opinion, of course) to not
use the 'augmenting-types' capability, given the context mentioned
earlier in the same post [Douglas Crockford's note about the need of
being careful when there are other scripts in the page]. "Not to use
something" is totally different from "mutilating something".
 
T

Thomas 'PointedEars' Lahn

JR said:
No, it's prudence against the many that *think* they know what they're
doing.

That is a non sequitur. Why support incompetence?
The cemetery is full of fearless men.

False analogy.
No, you are mistaken.

I am not.
Read again: I did not advise anyone to 'mutilate' JS, instead I commented
(as an opinion, of course) to not use the 'augmenting-types' capability,
given the context mentioned earlier in the same post [Douglas Crockford's
note about the need of being careful when there are other scripts in the
page].

In this very example augmenting the prototype object can do no harm at all
except to those who are stupid enough to for-in over String instances or
values without considering enumerable properties. Your categorical "do not
use" principle is in effect shifting the responsibility entirely from the
library user to the library author. Have you not seen enough inefficient
jQuery nonsense to see that this is a flawed concept?
"Not to use something" is totally different from "mutilating something".

I was not referring to that part or to your statements in particular there.


PointedEars
 
S

Scott Sauyet

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

My English copy of the book (2008, first edition) lists the OP's
version of the code, and then later in the same section lists the one
you supply, introduced by "The prototypes of the basic types are
public structures, so care must be taken when mixing libraries. One
defensive technique is to add a method only if the method is known to
be missing."

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

Clearly this is an improvement on the original. I agree with whoever
mentioned that this should have a verb, "setMethod", "addMethod", or
some such.

I don't much like modifying the prototypes of the built-in objects,
although I understand that it can be useful and powerful to do so in
at least some circumstances. But Crockford's only justification for
this is only that "[W]e no longer have to type the name of the
prototype property. That bit of ugliness can now be hidden." His
original version (as supplied by the OP) seems to have no advantage.
I certainly don't see that this:

Number.method('integer', function () {
return Math[this < 0 : 'ceil' : 'floor'](this);
});

is any less ugly than this:

Number.prototype.integer = function () {
return Math[this < 0 : 'ceil' : 'floor'](this);
};

But when you add in the error checking, it is clearly less ugly than
this:

if (!Number.prototype.integer) {
Number.prototype.integer = function () {
return Math[this < 0 : 'ceil' : 'floor'](this);
};
}

So I think a version of this technique would be useful if you do
choose to enhance these prototypes.

-- Scott
 
J

JR

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

My English copy of the book (2008, first edition) lists the OP's
version of the code, and then later in the same section lists the one
you supply, introduced by "The prototypes of the basic types are
public structures, so care must be taken when mixing libraries.  One
defensive technique is to add a method only if the method is known to
be missing."
   Function.prototype.method = function (name, func) {
       if (!this.prototype[name]) {
           this.prototype[name] = func;
       }
   };

Clearly this is an improvement on the original.  I agree with whoever
mentioned that this should have a verb, "setMethod", "addMethod", or
some such.

I don't much like modifying the prototypes of the built-in objects,
although I understand that it can be useful and powerful to do so in
at least some circumstances.  But Crockford's only justification for
this is only that "[W]e no longer have to type the name of the
prototype property.  That bit of ugliness can now be hidden."  His
original version (as supplied by the OP) seems to have no advantage.
I certainly don't see that this:

    Number.method('integer', function () {
        return Math[this < 0 : 'ceil' : 'floor'](this);
    });

is any less ugly than this:

    Number.prototype.integer = function () {
        return Math[this < 0 : 'ceil' : 'floor'](this);
    };

But when you add in the error checking, it is clearly less ugly than
this:

    if (!Number.prototype.integer) {
        Number.prototype.integer = function () {
            return Math[this < 0 : 'ceil' : 'floor'](this);
        };
    }

So I think a version of this technique would be useful if you do
choose to enhance these prototypes.

  -- Scott

Brilliant! ITA.

Cheers,
JR
 
G

Garrett Smith

Eric said:
It works in Safari 2.04; I would expect that people who are stuck with
OS X 10.4 would still run system updates.

Ah but 10.4 can get Safari 3 and 4. 10.3 users are a different matter.

Now for 10.3, you'd need to support Safari 1. I do know any way to test
Safari 1 on 10.4.

Apple bundles the Browser with the operating system, but somehow does
not suffer the legal troubles that Microsoft has experienced in doing
the same. Apple does a lot worse things and gets away with those, too.

Apple a good example what is wrong with business in America.
 
D

Dmitry A. Soshnikov

If you know that then why did you make it look as though David wrote the
word 'terrible' four times ?

I've already answered to you. Should I repeat twice? Please ask if
something still unclear, I will.

/ds
 
J

Jorge

Ah but 10.4 can get Safari 3 and 4. 10.3 users are a different matter.

10.3 users can install FF2 or iCab 3 or iCab 4 or Opera 8 or 9 or 10,
or ...
Now for 10.3, you'd need to support Safari 1. I do know any way to test
Safari 1 on 10.4.

Safari 1 is as obsolete as IE5. There's no need to support that (see
above the plenty of alternative options that 10.3 users have)
Apple bundles the Browser with the operating system, but somehow does
not suffer the legal troubles that Microsoft has experienced in doing
the same.

Only that to uninstall Safari all you need to do is to trash its icon,
and doing that won't "damage the operating system" -as used to be the
case when uninstalling IE- (http://en.wikipedia.org/wiki/
United_States_v._Microsoft and http://en.wikipedia.org/wiki/Removal_of_Internet_Explorer).
And the OSX APIs that Safari uses are public so that other browser
makers can use them too (unlike the IE/Windows combo), and that
Safari's source code is open, public and free. And that Apple OSs up
to OSX (year 2001), came with both IE and NetScape Navigator installed
by default.
Apple does a lot worse things and gets away with those, too. Apple a goodexample what is wrong with business in America.

People's idiocy in general (and some people's idiocy in particular) is
much worse a problem currently than Apple's business practices. BTW,
here's some -hot- dirty play being made to Apple, see see:
http://stadium.weblogsinc.com/engadget/files/apple-nokia-answer.pdf
 
J

Jorge

Ah but 10.4 can get Safari 3 and 4. 10.3 users are a different matter.

10.3 users can install FF2 or iCab 3 or iCab 4 or Opera 8 or 9 or 10,
or ...
Now for 10.3, you'd need to support Safari 1. I do know any way to test
Safari 1 on 10.4.

Safari 1 is as obsolete as IE5. There's no need to support that (see
above the plenty of alternative options that 10.3 users have)
Apple bundles the Browser with the operating system, but somehow does
not suffer the legal troubles that Microsoft has experienced in doing
the same.

Only that to uninstall Safari all you need to do is to trash its icon,
and doing that won't "damage the operating system" -as used to be the
case when uninstalling IE- (http://en.wikipedia.org/wiki/
United_States_v._Microsoft and http://en.wikipedia.org/wiki/Removal_of_Internet_Explorer).
And the OSX APIs that Safari uses are public so that other browser
makers can use them too (unlike the IE/Windows combo), and that
Safari's source code is open, public and free. And that Apple's OSs up
to OSX (year 2001), came with both IE and NetScape Navigator installed
by default.
Apple does a lot worse things and gets away with those, too. Apple a goodexample what is wrong with business in America.

People's idiocy in general (and some people's idiocy in particular) is
much worse a problem currently than Apple's business practices. BTW,
here's some -hot- dirty play being made to Apple, see see:
http://stadium.weblogsinc.com/engadget/files/apple-nokia-answer.pdf
 
M

Matt Kruse

Have read Douglas Crockfore's JavaScript The Good Parts, it recommend
Augmenting Types, e.g.
String.method('trim', function() {
    return this.replace(/^\s+|\s+$/g, '');
});

There have been a number of replies. I'll just post some pros/cons to
adding the methods _only if they don't already exist_:

PRO:
1) Consistent API defined by specs, not some additional list of
functions developers need to learn
2) Native method used if it already exists, so you take advantage of
browser optimizations
3) As browsers are upgraded and fast native methods are added, they
will automatically be used without changing your code

CON:
1) Other code on your page may break due to naive "feature tests" and
object inferences that you have now corrected, or dumb for loops that
iterate over your added properties.
2) User-defined functionality may not exactly match the browser's
native functionality.
3) Browsers without the method may be upgraded to add the method, but
add bugs or quirks and make it _worse_ than the user-defined function
and/or break functionality.
4) Other code on your page may choose to do the same thing, but use
different logic than you. You won't be sure if your methods have been
"stepped on" and replaced.
5) You're likely delivering a lot of code to define methods in
browsers that may not need any of it because native methods already
exist.

Of course, if you over-write methods even if they exist you may get
consistent user-defined behavior across all browsers, but you lose
native methods and open yourself up to introducing bugs, so that isn't
a good idea.

CONCLUSION:
I think that implementing a few methods that are in the standards and
add convenience but may not exist in older browsers is not a bad idea.
However, you shouldn't have a single file that you include everywhere
that implements every known method that may be lacking, because that's
a waste of bytes and processing for browsers that don't need it. Just
implement the methods you'll be using on the page where you want them,
if possible.

Matt Kruse
 
D

David Mark

David said:
And I think it bears pointing out that there is no recovery from
[an "automation server can't create object ..."] exception.

Wrong, try-catch can handle this.

You misquoted me. (!) Are you kidding? You know exactly what I was
referring to (if not, see screen shot). Obviously the error was _not_
caught by try-catch, therefore there is no possible recovery
(regardless of the wording of the dialog in the screen shot). Clear?
 
D

David Mark

David said:
And I think it bears pointing out that there is no recovery from
[an "automation server can't create object ..."] exception.

Wrong, try-catch can handle this.

You misquoted me. (!) Are you kidding? You know exactly what I was
referring to (if not, see screen shot). Obviously the error was _not_
caught by try-catch, therefore there is no possible recovery
(regardless of the wording of the dialog in the screen shot). Clear?
 
D

David Mark

It works in Safari 2.04; I would expect that people who are stuck with
OS X 10.4 would still run system updates.

So say it was 2.01 (or whatever). It's irrelevant as Safari 2 is not
the only browser without that method.

Huh? Using it without detecting it means the script blows up,
possibly leaving the document in an unusable state. Scripts are not
allowed to die without permission.

That's always been the point (and it's a good one). ;)
 
E

Eric Bednarz

Garrett Smith said:
Eric Bednarz wrote:

[.hasOwnProperty() in Safari 2]
Ah but 10.4 can get Safari 3 and 4. 10.3 users are a different matter.

My mistake, thanks for the correction.
Apple bundles the Browser with the operating system, but somehow does
not suffer the legal troubles that Microsoft has experienced in doing
the same. Apple does a lot worse things and gets away with those, too.

Compared to Adobe, Apple is a socialistic summer camp.
Apple a good example what is wrong with business in America.

Business in America suffers from faulty ECMAScript implementations?
 

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

Latest Threads

Top