1

I was reading about JavaScript Number object on Mozilla Developer Network. I am new to this. Below is my script:

var number = 16;
console.log( Number.prototype.toExponential(number) );
console.log( Number.prototype.toFixed(number) );
console.log( Number.prototype.toPrecision(number) );
// DON'T UNDERSTAND WHAT THIS DOES
// console.log( Number.prototype.toSource(number) );
console.log( Number.prototype.valueOf(number) );  

and the output:

0.0000000000000000e+0 
0.0000000000000000 
0.000000000000000 
0   

I am wondering why I am getting all zeros despite number = 16. Please help me in understanding this. :)

An SO User
  • 24,612
  • 35
  • 133
  • 221

4 Answers4

3

You have to have:

var number = 16;
console.log(number.toExponential());
console.log(number.toFixed());
console.log(number.toPrecision());

With prototype you can define you own methods and properties of objects

With prototype basically extending objects

Here is a simple example of prototype:

Number.prototype.isPrime = function() {
    if ( this === 0 || this === 1 ) {
        return false;
    }
    for ( var i = 2; i < this; i++ ) {
        if ( this % i === 0 ) {
            return false;
        }
    }
    return true;
};

var arr = [2,4,5,13,15,121];

for ( var i = 0; i < arr.length; i++ ) {
    console.log(arr[i].isPrime());
}

In this example this keyword refers to number object (so you don't have to pass any argument in function for manipulation)

JSFIDDLE

Take a look on prototype

nanobash
  • 5,419
  • 7
  • 38
  • 56
  • 1
    But please never change Host objects in real life. – phylax Apr 13 '14 at 17:25
  • Well now I am having a hard time deciding whose answer to accept. xD – An SO User Apr 13 '14 at 17:25
  • 1
    @phylax What does that mean ? :) – An SO User Apr 13 '14 at 17:25
  • 1
    Host objects are `Number`, `Array`, `String` ... changing their behaviour is considered bad practice. Read more here: http://stackoverflow.com/questions/6223449/why-is-it-frowned-upon-to-modify-javascript-objects-prototypes – phylax Apr 13 '14 at 17:28
  • 2
    @phylax: Those aren't Host objects, and in real life it can be useful to extend their prototypes. Different people have different *opinions* on the matter, but there's nothing inherently wrong with it. It's more situational. – cookie monster Apr 13 '14 at 17:30
  • *looks bewildered.* I just asked for help with my `Number` functions. Did I just start a JavaScript war ? LOL #justKidding – An SO User Apr 13 '14 at 17:30
  • 1
    @phylax Like cookie monster said I don't see any problem in this, anyways I just showed an example how `prototype` works – nanobash Apr 13 '14 at 17:32
  • Ok, didn't wanted to start ar war here. More about host objects and native objects: http://stackoverflow.com/questions/7614317/what-is-the-difference-between-native-objects-and-host-objects - of course there is no law which forbits it but not to mess with those objects is a rule wich i took from people knowing much more about JavaScript then me and to me it was a good rule. – phylax Apr 13 '14 at 17:44
  • 1
    @phylax The way you are talking `prototype` is not good practice not only `Host` objects but also in user defined functions, because `methods` can be defined inside a `function` not outside of it as during initialization firstly invoked inside defined ones – nanobash Apr 13 '14 at 17:47
  • 1
    @phylax: There will always be people who adopt a certain set of coding conventions and then go around telling people that they are "best practices" and deviation from them are "bad practice". In reality, the true "best practice" is to fully understand the ramifications of *any* approach to programming and to decide what to do in a given situation based on that understanding. – cookie monster Apr 13 '14 at 17:55
  • 1
    ...if we can never change native or host prototypes, then we could never polyfill missing methods. That would be a terribly unfortunate consequence of applying made-up rules in an unnecessarily broad manner. Even jQuery modifies host objects to implement its `jQuery.cache`. – cookie monster Apr 13 '14 at 17:59
  • @ToKeN i dont fully understand what you are trying to say. You say its ok to modify prototype of objects i havent implemented by my self because those objects could modify their own prototypes during runtime? That sounds like an argument not to do it. – phylax Apr 13 '14 at 18:11
  • @cookiemonster i allways readjust my conventions by things i read and compare to things others have written. I just searched 'javascript host objects prototype' and found more then one article about it, explaining why its bad. I'm still reading. And by the way, there was no article saying its good. – phylax Apr 13 '14 at 18:16
  • @phylax The only `bad` thing about it could be that through the iteration of objects there will be the name of extended function by prototype which can easily solved with `hasOwnProperty`, anyways do your best as you think it is good for you – nanobash Apr 13 '14 at 18:26
  • @phylax: That's because people are far more likely to write about things they perceive to be bad, rather than things that are neutral. It's never good to take a solution to a single situation where something can have an ill effect and apply it to all situations. Again, a good developer will understand the ramifications of every approach to coding, and make decisions on a case by case basis. – cookie monster Apr 13 '14 at 18:26
  • ...and jQuery's "plugin" system is entirely based on extending a `.prototype` of a constructor that the end developer didn't implement. – cookie monster Apr 13 '14 at 18:29
  • Anyhow, i want to state one last thing which could have been misunderstood. Im *not* saying modifying prototype is a bad thing in general. I'm talking about host objects and native objects. jQuery is explicitly meant to be extended this way and does not apply to this toppic. – phylax Apr 13 '14 at 19:46
  • @phylax: Any problem encountered by modifying a native, host or any other prototype can be equally encountered by modifying jQuery's prototype. There's no difference. There's nothing special about jQuery's constructor that would make it any different from any other. Every mutable `.prototype` is explicitly meant to be extended if one chooses to do so. The same considerations need to be made in all cases. Your distinction is arbitrary. – cookie monster Apr 13 '14 at 21:18
2

Number.prototype functions live on actual numbers (the prototype is the definition for a specific type. String variables have functions that live on String.prototype, arrays have functions defined on Array.prototype, etc. http://javascript.crockford.com/prototypal.html is a good starting place to learn about prototype inheritance), so just call number.toFixed(), number.toFixed() etc. You can even do (16).toString() etc.

You're calling the function "on nothing" by calling the prototype function, instead of "on 16".

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • Please explain the `.prototype` concept to me :) I have never seen it before :) – An SO User Apr 13 '14 at 17:18
  • 2
    it's the entire underpinning of object oriented javascript... =) Objects have types that are defined by a prototype, and instances share all prototype functions. You definitely want to read up on it with something like "JavaScript: the good parts" to familiarise yourself with the very core of how JavaScript works =) – Mike 'Pomax' Kamermans Apr 13 '14 at 17:20
  • So far what I have learned has been how to use JavaScript rather than the workings. Like I said, I am new to this. Any good book you recommend ? :) – An SO User Apr 13 '14 at 17:21
  • I updated the answer with a useful link for you, the rest of Crockford's writing on JavaScript is generally worth reading, too, if you're learning JavaScript – Mike 'Pomax' Kamermans Apr 13 '14 at 17:22
  • @LittleChild Take a look at my example – nanobash Apr 13 '14 at 17:24
  • @LittleChild: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model – Felix Kling Apr 13 '14 at 17:35
2

You will have better luck if you do the following:

var number = new Number(16);
console.log(number.toExponential());
console.log(number.toFixed());
console.log(number.toPrecision());
console.log(number.valueOf());

Note* It's preferable not to use numbers in javascript this way unless you have a specific need to avoid primitives.

The reason you are getting 0 is because the Number prototype defaults to zero if it is not instantiated.

Number is a prototype which is designed semantically to be used to spawn new objects which inherit these methods. These methods are not designed to be called directly from the Number prototype, but instead from the numbers themselves. Try the following:

(16).toExponential();

You have to wrap the number in parenthesis so the interpreter knows you're accessing methods and not defining a floating point.

The important thing here to understand is that the Number prototype provides all the methods that all numbers will inherit in javascript.

To explain further why you are getting a 0, the methods on the Number prototype are intended to be "bound" to a number object. They will use the bound object for input and will ignore any arguments. Since they are bound to the default Number object, the default number is 0, and therefore all methods will return their version of 0.

There is a way in javascript to rebind methods to an object using the "call" method (there's also bind and apply):

Number.prototype.toExponential.call(16);
James M. Lay
  • 2,270
  • 25
  • 33
  • 1
    You should not advocate the use of `new Number`. Some less experience dev might pick that up and run into all sorts of problems later on. I like the rest of the answer though :) – Felix Kling Apr 13 '14 at 17:38
  • I'm merely using it to demonstrate how the Number prototype is instantiated. Of course, I also provide the "primitive" way of accessing the associated methods. – James M. Lay Apr 13 '14 at 17:39
  • However, if I may ask, why is the use of `new Number` frowned upon? – James M. Lay Apr 13 '14 at 17:40
  • 1
    Mainly because it makes comparison inconsistent. E.g. `new Number(16) === new Number(16)` is `false`. `new Number(0) < new Number(16)` is `true`. Sideeffects of working with an object instead of a primitive value. – Felix Kling Apr 13 '14 at 17:41
1

try this:

var number = 16;
console.log( Number.prototype.toExponential.call(number) );

Notice the call() which calles the method toExponential of the Number object on an instance.

phylax
  • 2,034
  • 14
  • 13