Math ugliness.

J

Jorge

Hi,

Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };
Number.prototype.asin= function () { return Math.asin(+this); };
Number.prototype.pow= function (p) { return Math.pow(+this, p); };
Number.prototype.sqrt= function () { return Math.sqrt(+this); };
Number.prototype.rnd= function () { return this*Math.random(); }

etc..

x= 16;
x.sqrt()
--> 4

x="256";
(+x).pow(2) //be sure to call the right .proto
--> 65536

(1.234).sin().asin()
--> 1.234

1..asin() * 2
-> 3.141592653589793

(2).pow(10)
--> 1024

2..pow(10).sqrt()
--> 32

(100).rnd()
-> 0 <= n < 100
 
C

Cody Haines

Jorge said:
Hi,

Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };
Number.prototype.asin= function () { return Math.asin(+this); };
Number.prototype.pow= function (p) { return Math.pow(+this, p); };
Number.prototype.sqrt= function () { return Math.sqrt(+this); };
Number.prototype.rnd= function () { return this*Math.random(); }

etc..

x= 16;
x.sqrt()
--> 4

x="256";
(+x).pow(2) //be sure to call the right .proto
--> 65536

(1.234).sin().asin()
--> 1.234

1..asin() * 2
-> 3.141592653589793

(2).pow(10)
--> 1024

2..pow(10).sqrt()
--> 32

(100).rnd()
-> 0 <= n < 100
Just out of curiosity, does IE support this? I don't see why it
wouldn't, just making sure
 
R

RobG

Hi,

Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };

I'm curious about the use of unary +. Presumably the identifier is
resolved to a number primitive in the first place, otherwise x.sin
wouldn't resolve to Number.prototype.sin.

Or have I missed something?


[...]
x="256";
(+x).pow(2) //be sure to call the right .proto
--> 65536

So if x must be a number in order for the right property to be found,
why must it also be converted inside the function?
 
T

Thomas 'PointedEars' Lahn

Cody said:
Jorge said:
Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };
Number.prototype.asin= function () { return Math.asin(+this); };
Number.prototype.pow= function (p) { return Math.pow(+this, p); };
Number.prototype.sqrt= function () { return Math.sqrt(+this); };
Number.prototype.rnd= function () { return this*Math.random(); }

etc..

x= 16;
x.sqrt()
--> 4

x="256";
(+x).pow(2) //be sure to call the right .proto
--> 65536

(1.234).sin().asin()
--> 1.234

1..asin() * 2
-> 3.141592653589793

(2).pow(10)
--> 1024

2..pow(10).sqrt()
--> 32

(100).rnd()
-> 0 <= n < 100
[...]

Just out of curiosity, does IE support this? I don't see why it
wouldn't, just making sure

JScript 5.6.6626 as of IE 6.0.2800.1106 supports this. It stands to reason
that later versions of JScript and Internet Explorer, therefore other
MSHTML-based browsers, would also support this (I cannot test them here
yet).

In fact, given that, according to Editions 3 and 5 of the ECMAScript
Language Specification, when evaluating the CallExpression's
/MemberExpression/ any primitive value would be converted into an
appropriate value of type Object (ES3/5, 11.2.3, 11.2.1, and 9.9), this
SHOULD work everywhere where `Number.prototype' is supported (which AFAIK
excludes only JavaScript 1.0 as of Netscape 2.x, and JScript 1.0 as of IE
3.0 and IIS 3.0 ).¹ Tests with JavaScript, Apple JSC, Opera ECMAScript,
and KJS confirmed this a while ago; I could also confirm it for Google V8
2.0 as of Chrome 5.0.307.7 by now. (In fact, this idea is anything but
original.)

However, the better question is: Does it make sense to do this?

You could lose the explicit type conversion to begin with (as it is done
implicitly by the algorithms of the built-in methods of `Math'; see ES3/5,
15.8.2).

Still, with regard to memory efficiency your stack would be one level
higher than without it, and with regard to runtime efficiency you would be
paying for one call more than without it. Stack space being a scarce
resource, and calls being rather expensive, this approach does not appear
to make much sense.


PointedEars
___________
¹ To be sure of that, I have debugged the algorithms of ECMAScript Ed. 5,
and compared with Ed. 3; I can post more detailed results of my
research if anyone is interested.
 
T

Thomas 'PointedEars' Lahn

kangax said:
I was curious about this too.

I'm guessing ToNumber conversion is there to make method intentionally
generic, similar to, say, `String.prototype.trim` from ES5, which passes
its this value through ToString before trimming a value.

It is still superfluous as the methods of `Math' already call ToNumber() on
each of their arguments.


PointedEars
 
J

Jorge

I'm curious about the use of unary +. Presumably the identifier is
resolved to a number primitive in the first place, otherwise x.sin
wouldn't resolve to Number.prototype.sin.

Or have I missed something?

I believe it gets -automatically- wrapped in an object just before -in
order to do- the property lookup... ¿?
[...]
x="256";
(+x).pow(2) //be sure to call the right .proto
--> 65536

So if x must be a number in order for the right property to be found,
why must it also be converted inside the function?

I did that because I recall that new Number(3) !== new Number(3): IOW,
because "this" is -supposedly- an object.

This idea occurred to me yesterday late at night while watching
Crockford on JS video #2, and I just posted it here on the fly without
much/any further ado/testing.
 
J

Jorge

(...) In fact, this idea is anything but original. (...)

And then came Pointy, decided to spoil the fun... :)

I've never seen it before.. who, where, when ? Have you got any urls,
plz ?
 
D

Dmitry A. Soshnikov

Hi,

Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Artifact of not - that's questionable, because some methods fit to
numbers (e.g. .round(), other), some by semantic - for mathematical
actions and could be placed in separate Math'ematical module.

Other question is style of code. I always don't like to repeat some
chunks of code, I always try to decrease such repetitions. That's why
I really don't like new approach in ES5 for methods to work with
objects which are placed not in `Object.prototype' letting to work in
OOP-style, but in `Object' constructor itself. I know the reasons why
it was done so (such a "protection" if simple object will have own
such property), but that seems to my ugly too (just an abstract
example):

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

This repetition of Object.-Object.-Object. is really `heavy'. The
first thing which also can be done in ES5 (to make it more comfortable
in some viewpoint) - is definition of the same methods in
`Object.prototype' (with [[Enumerable]] = false), allowing elegant
chains, decreasing of the repeated chunks of code such as `Object.':

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

By the way, e.g. in Ruby, many of this methods (and for numbers and
for objects) are instance methods:

1.5.round()
{'a' => 10}.freeze()

and so on.

/ds
 
J

Jorge

By the way, e.g. in Ruby, many of this methods (and for numbers and
for objects) are instance methods:

1.5.round()
{'a' => 10}.freeze()

and so on.

That's the way it ought to be, imo, and JS is powerful enough that
allows for sculpting it at your liking.
 
J

Jorge

- implies two numeric primitive to Number object type-conversations

One sometimes has to wonder what's really going on inside one's
browser... "primitive" "conversations" ? LOL.
 
J

Jorge

Artifact of not - that's questionable, because some methods fit to
numbers (e.g. .round(), other), some by semantic - for mathematical
actions and could be placed in separate Math'ematical module.

Why the hell given that numbers are objects too, can't they have their
own methods in their own prototype ?
Why if not to copy Java style were they moved into a separate "Math"
object ?
In order to make it an "optional" object (as Crockford states in that
video #2) for lesser ES implementations ?
 
T

Thomas 'PointedEars' Lahn

kangax said:
Thomas said:
Cody said:
Jorge wrote:
Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };
[...]
(1.234).sin().asin()
[...]

Just out of curiosity, does IE support this? I don't see why it
wouldn't, just making sure

[...]
In fact, given that, according to Editions 3 and 5 of the ECMAScript
Language Specification, when evaluating the CallExpression's
/MemberExpression/ any primitive value would be converted into an
appropriate value of type Object (ES3/5, 11.2.3, 11.2.1, and 9.9), this
SHOULD work everywhere where `Number.prototype' is supported (which
AFAIK excludes only JavaScript 1.0 as of Netscape 2.x, and JScript 1.0
as of IE 3.0 and IIS 3.0 ).¹ [...]
___________
¹ To be sure of that, I have debugged the algorithms of ECMAScript Ed.
5,
and compared with Ed. 3; I can post more detailed results of my
research if anyone is interested.

I'm interested.

In the following, I will use `Number.prototype.sin' as defined above and
`(1.234).sin()' for the example.

The basic productions that apply to the expression

(1.234).sin()

in both Editions are:

CallExpression :
MemberExpression Arguments

MemberExpression :
PrimaryExpression
MemberExpression . Identifier

PrimaryExpression :
Literal
( Expression )

Expression :
AssignmentExpression

...

LeftHandSideExpression :
NewExpression

NewExpression:
MemberExpression

Literal ::
NumericLiteral

NumericLiteral ::
DecimalLiteral

DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigits_opt ExponentPart_opt

Arguments :
()

As a result, the following unifications take place:

In the algorithm for the production
CallExpression : MemberExpression Arguments
(section 11.2.3):

CallExpression := (1.234).sin()
MemberExpression := (1.234).sin
Arguments := ()

And the following steps:

1. Evaluate MemberExpression.

In the algorithm for
MemberExpression : MemberExpression [ Expression ]
(section 11.2.1):

MemberExpression := (1.234)
Expression := "sin"

Steps per ES3F:

1. Evaluate MemberExpression.
--> Result(1) := 1.234
2. Call GetValue(Result(1)).
--> Result(2) := 1.234
3. Evaluate Expression.
--> Result(3) := "sin"
4. Call GetValue(Result(1)).
--> Result(4) := "sin"
5. Call ToObject(Result(2)).
^^^^^^^^^^^^^^^^^^^^^^^^^

(9.9) ToObject

The operator ToObject converts its argument to a value
of type Object according to the following table:

[...]
Number Create a new Number object whose [[value]] property is
set to the value of the number. See section 15.7 for a
description of Number objects.
[...]

--> Result(5) := new Number(1.234)

6. Call ToString(Result(4)).
--> Result(6) := "sin"
7. Return Reference(base=Result(5), name=Result(6)):
--> Return Reference(base=new Number(1.234), name="sin").

It is thus quite obvious already that the primitive Number value is being
converted into an equivalent Number object that has the current value of
`Number.prototype' next in its prototype chain, and we can skip analyzing
the subsequent steps for ES3F in detail. JFTR, they are:

2. Evaluate /Arguments/, producing an internal list of argument values
(section 11.2.4).
3. Call GetValue(Result(1)).
4. If Type(Result(3)) is not Object, throw a *TypeError* exception.
5. If Result(3) does not implement the internal [[Call]] method, throw
a TypeError exception.
6. If Type(Result(1)) is Reference, Result(6) is GetBase(Result(1)).
Otherwise, Result(6) is *null*.
7. If Result(6) is an activation object, Result(7) is *null*.
Otherwise, Result(7) is the same as Result(6).
8. Call the [[Call]] method on Result(3), providing Result(7) as the
*this* value and providing the list Result(2) as the argument values.
9. Return Result(8).

However, the conversion of the primitive value to an object for the purpose
of property lookup is a lot harder to see with the ES5 algorithms, which is
why I am going deeply into detail there:

(11.2.3) Function Calls

The production /CallExpression/ : /MemberExpression/ /Arguments/
is evaluated as follows:

1. Let /ref/ be the result of evaluating /MemberExpression/.

--> ref := Evaluate( (1.234).sin )

(11.2.1) Property Accessors

[...]
The production
/MemberExpression/ : /MemberExpression/ [ /Expression/ ]"
(equivalence of dot and bracket property accessor notation for
Identifiers; the ed.) is evaluated as follows:

MemberExpression := (1.234)
Expression := "sin"

1. Let /baseReference/ be the result of evaluating
/MemberExpression/.
--> baseReference := 1.234

2. Let /baseValue/ be GetValue(/baseReference/).
--> baseValue := GetValue(baseReference)
--> baseValue := 1.234

3. Let /propertyNameReference/ be the result of evaluating
/Expression/.
--> propertyNameReference := "sin"

4. Let /propertyNameValue/ be GetValue(/propertyNameReference/).
--> propertyNameValue := "sin"

5. Call CheckObjectCoercible(/baseValue/).
--> CheckObjectCoercible(1.234) exits normally

6. Let /propertyNameString/ be ToString(/propertyNameValue/).
--> propertyNameString := "sin"

7. If the syntactic production that is being evaluated is contained
in strict mode code, let /strict/ be *true*, else let /strict/ be
*false*.

We assume no strict mode here (it does not really matter for this
algorithm anyway) --> strict := false

8. Return a value of type Reference whose base value is /baseValue/
and whose referenced name is /propertyNameString/, and whose
strict mode flag is /strict/.
--> return Reference(base=1.234, name="sin", strict=false)

--> ref := Reference(base=1.234, name="sin", strict=false)

(11.2.3)
2. Let /func/ be GetValue(/ref/).
--> func := GetValue(ref)

(8.7.1) GetValue(V)

V := Reference(base=1.234, name="sin", strict=false)

1. If Type(/V/) is not Reference, return /V/.
--> Type(V) is Reference, continue.

2. Let /base/ be the result of calling GetBase(/V/).
--> base := GetBase(V)
--> base := 1.234 (section 8.7)

3. If IsUnresolvableReference(/V/), throw a *ReferenceError*
exception.

V := Reference(base=1.234, name="sin", strict=false)

(8.7)
IsUnresolvableReference(V) := (GetBase(V) == undefined)
--> IsUnresolvableReference(V) == false

--> Continue.

4. If IsPropertyReference(/V/), then

V := Reference(base=1.234, name="sin", strict=false)

(8.7)
IsPropertyReference(V) :=
Type(V) == Object || HasPrimitiveBase(V)

--> Type(V) == Number

HasPrimitiveBase(V) := Type(GetBase(V)) == Boolean
|| Type(GetBase(V)) == String
|| Type(GetBase(V)) == Number
--> HasPrimitiveBase(V) == true

--> IsPropertyReference(V) == true

a. If HasPrimitiveBase(V) is false, then let /get/ be the
[[Get]] internal method of /base/, otherwise let /get/
be the special [[Get]] internal method defined below.
--> HasPrimitiveBase(V) == true
--> get := special [[Get]]

b. Return the result of calling the /get/ internal method
using /base/ as its *this* value, and passing
GetReferencedName(/V/) for the argument.

--> return get(this=1.234, "sin")
--> return special [[Get]](this=1.234, "sin")

1. Let O be ToObject(base).
^^^^^^^^^^^^^^^^^^^^^^^^
--> O := ToObject(1.234)
--> O := new Number(1.234)

2. Let /desc/ be the result of calling the
[[GetProperty]] internal method of /O/
with property name /P/.

desc := (new Number(1.234)).[[GetProperty]]("sin")

(8.12.2) [[GetProperty]] (P)

When the [[GetProperty]] internal method of /O/
is called with property name /P/, the following
steps are taken:

O := new Number(1.234)
P := "sin"

1. Let /prop/ be the result of calling the
[[GetOwnProperty]] internal method of /O/
with property name /P/.

prop :=
(new Number(1.234))[[GetOwnProperty]]("sin")

(8.12.1) [[GetOwnProperty]] (P)

When the [[GetOwnProperty]] internal method of
/O/ is called with property name /P/, the
following steps are taken:

1. If /O/ doesn’t have an own property with
name /P/, return *undefined*.

HasOwnProperty(new Number(1.234), "sin")
== false
--> return undefined

--> prop := undefined

2. If /prop/ is not *undefined*, return /prop/.
--> prop == undefined
--> Continue.

3. Let /proto/ be the value of the [[Prototype]]
internal property of /O/.
--> proto := (new Number(1.234))[[Prototype]]
--> proto := Number.prototype

4. If /proto/ is *null*, return *undefined*.
--> proto != null
--> Continue.

5. Return the result of calling the
[[GetProperty]] internal method of /proto/
with argument /P/.
--> return (
Number.prototype.[[GetProperty]]("sin"))

1. prop :=
Number.prototype[[GetOwnProperty]]("sin")

1. HasOwnProperty(Number.prototype, "sin")
== true, continue.
2. D := PropertyDescriptor()
3. X := Property(Number.prototype, "sin")
4. X is a data property (section 8.6), so
a. D.[[Value]] := X.[[Value]]
b. D.[[Writeable]] := X.[[Writeable]]
5. Else ... (skipped accordingly)
6. D.[[Enumerable]] := X.[[Enumerable]]
7. D.[[Configurable]] := X.[[Configurable]]
8. Return D.

--> return PropertyDescriptor(
Number.prototype, "sin", attribs)

--> desc := PropertyDescriptor(
Number.prototype, "sin", attribs)

3. If /desc/ is undefined, return *undefined*.
--> PropertyDescriptor(...) != undefined, continue.

4. If IsDataDescriptor(/desc/) is *true*, return
desc.[[Value]].

--> IsDataDescriptor(PropertyDescriptor(...))
== true:

(8.10.2)
1. PropertyDescriptor(Number.prototype, "sin",
attribs) != undefined, continue.
2. PropertyDescriptor(Number.prototype, "sin",
attribs).[[Value]] present, continue.
3. Return true.

--> Return PropertyDescriptor(...).[[Value]],
--> Return Number.prototype.sin.

--> return Number.prototype.sin

--> func := Number.prototype.sin

(11.2.3)
3. Let /argList/ be the result of evaluating /Arguments/, producing an
internal list of argument values (see 11.2.4).
--> argList := List()

4. If Type(/func/) is not Object, throw a *TypeError* exception.
--> Type(Number.prototype.sin) == Object, continue.

5. If IsCallable(/func/) is *false*, throw a *TypeError* exception.
--> IsCallable(Number.prototype.sin) == true, continue.

6. If Type(/ref/) is Reference, then
--> Type(Reference(base=1.234, name="sin", strict=false))
== Reference, so

a. If IsPropertyReference(/ref/) is true, then
--> IsPropertyReference(
Reference(base=1.234, name="sin", strict=false))
== true, so

i. Let thisValue be GetBase(/ref/).
--> thisValue := GetBase(ref)
--> thisValue := 1.234

b. Else ... (skipped accordingly)

7. Else ... (skipped accordingly)

8. Return the result of calling the [[Call]] internal method on /func/,
providing /thisValue/ as the *this* value and providing the list
/argList/ as the argument values.

--> return (Number.prototype.sin.[[Call]](
this=1.234, arguments=List())

(13.2.1) [[Call]]

When the [[Call]] internal method for a Function object /F/ is
called with a *this* value and a list of arguments, the
following steps are taken:

1. Let /funcCtx/ be the result of establishing a new execution
context for function code using the value of /F/'s
[[FormalParameters]] internal property, the passed arguments
List /args/, and the *this* value as described in 10.4.3.

--> funcCtx := ExecutionContext(
formalParameters=
Number.prototype.sin.[[FormalParameters]],
arguments=List(),
this=1.234)

2. Let result be the result of evaluating the /FunctionBody/
that is the value of /F/'s [
Code:
] internal property. If
/F/ does not have a [[Code]] internal property or if its
value is an empty FunctionBody, then result is (normal,
undefined, empty).

--> result := Evaluate(Number.prototype.sin.[[Code]])

3. Exit the execution context /funcCtx/, restoring the previous
execution context.
--> Exit(funcCtx), ...

4. If /result/.type is |throw| then throw /result/.value.
--> result.type == normal, continue.

5. If /result/.type is |return| then return /result/.value.
--> result.type == return
--> return /result/.value

--> return the equivalent of
Number.prototype.sin.apply(1.234, argList)

--> return Math.sin(+1.234)
--> return Math.sin(1.234)


What I found most interesting here is that the primitive value is converted
to an object solely for the purpose of property lookup; and that the
primitive value, _not_ a reference to that object becomes the `this' value
of the called method.  (IOW, if the `this' value of such a method is used
repeatedly with property accessors, it could be more efficient to convert
it to an object once explicitly, and then use the object reference
instead.)

I have also learned in the process that the more complex algorithms of ES5
do have a purpose beyond simply much a greater abstraction level; for
example, they support the implementation of mutable property attributes
like [[Enumerable]] -- which finally would allow such nice features like

var o = {foo: "bar"};

/* shows "foo" */
for (var p in o) console.log(p);

Object.defineProperty(o, "bar", {enumerable: false});

/* shows nothing */
for (p in o) console.log(p);

(if they were implemented; not so in JavaScript 1.8.1 as of
Firefox/Iceweasel 3.5.6 or any other widely distributed implementation¹) --
and facilitate making the difference between data properties and accessor
properties, i.e. normal properties on the one hand, and properties with
getters/setters on the other hand (already implemented there and
elsewhere¹):

var o = {
_bar: "",
get foo() { return +this._bar; },
set foo(x) { this._bar = String(+x + 19); }
};

o.foo = "23";

/* shows 42 as a number */
console.log(o.foo);


PointedEars
___________
¹  <http://www.robertnyman.com/javascript/javascript-getters-setters.html>
 
T

Thomas 'PointedEars' Lahn

Richard said:
In ES3 the - this - keyword always refers to an object, so you are
guaranteed that it is never a primitive value. [...]

ISTM that I have just proved this to be a common misconception.


PointedEars
 
J

Jorge

Richard said:
In ES3 the - this - keyword always refers to an object, so you are
guaranteed that it is never a primitive value. [...]

ISTM that I have just proved this to be a common misconception.

He said *In*ES3*:

Number.prototype.test= function () { return typeof this; };
(1).test()
--> "object"
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Richard said:
In ES3 the - this - keyword always refers to an object, so you are
guaranteed that it is never a primitive value. [...]

ISTM that I have just proved this to be a common misconception.

Please ignore this. In fact, my research¹ proves that you are correct for
ES3(F), where the Reference value is computed using the conversion result as
base; not so in ES5 (I wonder what the rationale was).


PointedEars
___________
¹ <--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
 
T

Thomas 'PointedEars' Lahn

Stefan said:
On 17/02/10 11:52, Thomas 'PointedEars' Lahn wrote:

[snip impressive human-script-engine-mode text]

Thanks :) Some day soon I hope I can have *computed* what should happen
according to the Specification for any given input or at least any given
expression instead.
I have also learned in the process that the more complex algorithms of
ES5 do have a purpose beyond simply much a greater abstraction level;
for example, they support the implementation of mutable property
attributes like [[Enumerable]] -- which finally would allow such nice
features like

var o = {foo: "bar"};

/* shows "foo" */
for (var p in o) console.log(p);

Object.defineProperty(o, "bar", {enumerable: false}); ^^^^^
/* shows nothing */
for (p in o) console.log(p);

Shouldn't this still show "foo"?

It should, thanks. I meant to pass "foo", of course.


PointedEars
 
R

Richard Cornford

One sometimes has to wonder what's really going on inside one's
browser... "primitive" "conversations" ? LOL.

OK, "conversations" should have been "conversions" (automatic spelling
correction, which I usually have turned off because it is not very
good at guessing which words are likely to occur in the subjects I
write about).

Richard.
 
R

Richard Cornford

On Feb 17, 11:12 am, Thomas 'PointedEars' Lahn wrote:
... , my research¹ proves that you are correct for ES3(F),
where the Reference value is computed using the conversion
result as base; not so in ES5 (I wonder what the rationale
was).

You mean the rationale for designing a new language version
specification that is significantly incompatible with the (very long
established) preceding version (and so is going to give many people
headaches in the near future as ES 5 implementations replace ES 3
implementations in web browsers)?

As I recall from the discussions on the ES mailing lists there wasn't
much of a rationale, just vague talk of things like "security" and a
few outspoken supporters of the notion.

You may recall that Google Chrome had been observed to be getting this
aspect of ES3 wrong (with regard to String object methods in those
cases) long before there was an ES5 (or this change had been
proposed), so for at least one of the participants in the ECMA
committee getting the change passed meant not having to fix what had
previously been a faulty script engine.

Richard.
 
T

Thomas 'PointedEars' Lahn

Jake said:
Thomas said:
(...) In fact, this idea is anything but original. (...)

And then came Pointy, decided to spoil the fun... :)

I've never seen it before.. who, where, when ? Have you got any urls,
plz ? [...]

http://www.prototypejs.org

The idea of augmenting built-in prototypes, particularly Number.prototype,
is much, much older than that. It dates back to at least 2001 CE. Google
is your friend. [psf 6.1]


PointedEars
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top