PDA

View Full Version : Prototypes Methods on Native Objects



Trinithis
05-26-2007, 06:26 AM
Number.prototype.valueOf = function() {return 1};
Number.prototype.toString = Number.prototype.valueOf;
var x = new Number(7);
alert(x); //Alerts 1


How would I instead be able to have those two methods return let's say 2 times the value of the number



Number.prototype.valueOf = function() {return /* Magic Code...something like (this*2) */};
Number.prototype.toString = Number.prototype.valueOf;
var x = new Number(7);
alert(x); //Should alert 14


Note: While I want to know how to do something like this in general for predefined objects, I know that the current example is not very practical.

jscheuer1
05-26-2007, 07:09 AM
Either:


Number.prototype.v = function() {return this*2};
Number.prototype.toString = Number.prototype.v;
var x = new Number(7);
alert(x); //Alerts 14

or:


Number.prototype.toString = function() {return this*2};
var x = new Number(7);
alert(x); //Alerts 14

I think that co-opting the valueOf method as a prototype is problematical when performing an operation such as multiplication due to the native action of valueOf. This appears to send the browser into an endless loop.

Trinithis
05-26-2007, 03:06 PM
I didn't realize it was too much recursion. All I got was some baffling exception error. Thanks for pointing me in the right direction. I got it to work with valueOf().


Number.prototype.nativeValueOf = Number.prototype.valueOf;
Number.prototype.valueOf = function() {
return this.nativeValueOf()*2;
}
Number.prototype.toString = function() {return this};
var x = new Number(7);
alert(x); //Alerts 14

Though it does not work if I define x like the following:


var x = Number(7);
//or
var x = 7;

I guess that's a good thing because then I do return this.nativeValueOf()*2, then I would have issues with the scalar 2 and also the 7 within the new Number(7).

Trinithis
05-26-2007, 03:23 PM
Oh, and one more thing, how can I do something like this:


Number.prototype.value = /*Something that equals this... all I keep getting is [object Window]*/
var x = new Number(7);
alert(x.value); //Should alert 7

This should be a property and not a method.

jscheuer1
05-26-2007, 05:03 PM
As far as I can tell and have seen, an object's prototype properties are set globally and can then be set individually, only after the individual object is initialized (or during the initialization process if an initialization function - a custom object constructor is used):


Number.prototype.value = 0;
var x = new Number(7);
x.value+=x;
alert(x.value); // alerts 7

There may well be some way around this requirement though. If you know of an example that shows this to be otherwise with some other object, it may be able to be adapted. The this keyword, when used in the global scope, should return the window object, just as you found that it did.

Twey
05-26-2007, 05:50 PM
But the value and string value of all numbers should not be twice the value of the actual number. Also, toString() should return a string.
Number.prototype.value = /*Something that equals this... all I keep getting is [object Window]*/
var x = new Number(7);
alert(x.value); //Should alert 7Yes, as John said you can't reference an instance before it's been created. You could use a factory method:
Number.withX = function() {
var n = Number.apply(null, Array.prototype.slice.call(arguments));
n.value = n;
return n;
};

var myNewNum = Number.withX(7);
myNewNum.value; // 7

jscheuer1
05-27-2007, 02:19 AM
alert(myNewNum.value);

returns undefined.

Twey
05-27-2007, 01:23 PM
Ah, yes, passed by value. That's irritating. OK:
Number.withSquare = function() {
var n = Number.apply(null, Array.prototype.slice.call(arguments));
n.square = g * g;
return {p:n};
};

var g = Number.withX(5);
g.p; // 5
g.p.square; // 25Not quite as convenient, alas.

jscheuer1
05-27-2007, 05:06 PM
That (as written, and alerting the results), doesn't do anything. If done like so:


Number.withSquare = function() {
var n = Number.apply(null, Array.prototype.slice.call(arguments));
n.square = g * g;
return {p:n};
};

var g = Number.withSquare(5);
alert(g.p); // 5
alert(g.p.square); // 25

I get 5 and undefined.

jscheuer1
05-27-2007, 05:32 PM
How about:


Number.withSquare = function(n) {
return {value:n, square:n*n};
};

var g = Number.withSquare(5);
alert(g.value); // 5
alert(g.square); // 25

But, with any of these, if Number.withSquare (or whatever) is a function, g is an object and will return as such:


alert(g);