Can't understand how to pass tests from Rosetta Code: Define a primitive data type

Tell us what’s happening:

Greetings, developers.
I can’t understand how do I pass a valid value when using new before.
As far as I can say, new is initializing a new object and therefore constructors don’t return nothing.

Your code so far


function Num(n) {
if(n < 1 || n > 10){
   throw new TypeError("Out of range");
}
if(typeof n == "string"){
  throw new TypeError("Not a Number");
}
this.value = n;
return this.value;
}

console.log(new Num(3) + new Num(4));

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36.

Challenge: Define a primitive data type

Link to the challenge:

The new keyword does the following things:

  1. Creates a blank, plain JavaScript object;
  2. Links (sets the constructor of) the newly created object to another object by setting the other object as its parent prototype;
  3. Passes the newly created object from Step 1 as the this context;
  4. Returns this if the function doesn’t return an object.

This challenge is a tricky one.
You need to override the valueOf method of the prototype in order to return the
value (of type number) you want from the primitive of the newly created object.

I think you have here everything you need to pass all the tests for that challenge.
If you feel that you need help or the solution, please do reach out.

It’s not really that tricky because the tests expect the return value to be an object, so just returning new Num(n) will work (as long as the invalid cases are handled, which they are).

@jsdisco
How do you pass this test: new Num(3) + new Num(4) ?

I’m not sure what you mean, the tests are running automatically, so all I have to do in the challenge is write a function that returns a new Number (or throws an error). You don’t have to manually test for all the stuff in the left panel.

Can you send me as a private message the solution you have written to pass all the tests without the use of valueOf please?

I am really curious of your approach as I was not able to do it in another way.

I’ll just throw the code here with spoilers:

Click for solution
function Num(n) {
  if (typeof(n) !== 'number'){
    throw new TypeError('Not a Number')
  };
  if (n < 1 || n > 10){
    throw new TypeError('Out of range')
  }
  return new Number(n);
}
1 Like

Thanks, I haven’t thought of that. It makes sense. Under the hood does the same thing. I normally use explicit coercion it just didn’t pass through my mind this time around.


function Num(n) {

  if(n < 1 || n > 10){
    throw new TypeError("Out of range");
  }

  if(isNaN(n)){
    throw new TypeError("Not a Number");
  }

  this.value = n;
  this.toString = () => String(this.value);
}

Num.prototype.valueOf = function() { return this.value; }

By boxing the value in Number you are returning the primitive of Number when test new Num(3) + new Num(4) is reached.

So the instance of Num is then an instance of Number, and Num just acts like a proxy for the Number constructor.

Same reason the toString function was not needed to be implemented because it is borrowed from the prototype of Number.

Nothing magic.

I think new Num(3) and new Number(3) both return an object, but if the tests try to add two of them, they’ll be converted to their primitive values. But yeah, nitpicking.