Proposal: a more consistent and stricter number converting function - Number.of()

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal: a more consistent and stricter number converting function - Number.of()

段垚
Hi,


Converting an arbitray value to a number in JS can be rather
inconsistent and unexpected:

* `null` and `undefined` are different: `+null === 0` but `+undefined`
is NaN.

* Empty string and non-nubmeric strings are different: `+"" === 0` but
`+"foo"` is NaN.


This problem can be worse because JSON only support finite numbers:

```

var total = 0;

total += JSON.parse(JSON.stringify({ "value": 0/0 })).value;

total === 0; //Oops, NaN is serialized as null, and then converted to 0

```

So I propose a more consistent and stricter number converting function:
`Number.of(value)`:

1. If `value` is `null` or `undefined`, return `NaN`;

2. If `value` is a number, return `value` itself;

3. If `value.valueOf()` returns a number, return that number, otherwise
return `NaN`.


This means all non-number values except those have number type
`.valueOf()` would be converted to NaN:


```

Number.of(null); // NaN

Number.of(''); //NaN

Number.of('1'); //NaN


var total = 0;

total += Number.of(JSON.parse(JSON.stringify({ "value": 0/0 })).value);

total; // NaN

```


What do you think?


Regards,

Duan, Yao



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: a more consistent and stricter number converting function - Number.of()

Claude Pache

> Le 24 févr. 2017 à 04:50, 段垚 <[hidden email]> a écrit :
>
> Hi,
>
>
> Converting an arbitray value to a number in JS can be rather inconsistent and unexpected:
>
> * `null` and `undefined` are different: `+null === 0` but `+undefined` is NaN.
>
> * Empty string and non-nubmeric strings are different: `+"" === 0` but `+"foo"` is NaN.
>
>
> This problem can be worse because JSON only support finite numbers:
>
> ```
>
> var total = 0;
>
> total += JSON.parse(JSON.stringify({ "value": 0/0 })).value;
>
> total === 0; //Oops, NaN is serialized as null, and then converted to 0
>
> ```
>
> So I propose a more consistent and stricter number converting function: `Number.of(value)`:
>
> 1. If `value` is `null` or `undefined`, return `NaN`;
>
> 2. If `value` is a number, return `value` itself;
>
> 3. If `value.valueOf()` returns a number, return that number, otherwise return `NaN`.
>
>
> This means all non-number values except those have number type `.valueOf()` would be converted to NaN:
>
>
> ```
>
> Number.of(null); // NaN
>
> Number.of(''); //NaN
>
> Number.of('1'); //NaN
>
>
> var total = 0;
>
> total += Number.of(JSON.parse(JSON.stringify({ "value": 0/0 })).value);
>
> total; // NaN
>
> ```
>
>
> What do you think?
>
>
> Regards,
>
> Duan, Yao
>


Depending on the concrete situation, you might not need yet another way to convert into number.

* If you know that your input is either a string or null/undefined (e.g., as the result of  `someHTMLElement.getAttribute('foo')`), you could use `Number.parseFloat()`, which will produce NaN for the empty string, null and undefined.

* If your issue is precisely with null/undefined, as it is the case in your JSON example, a more generic solution would be the null-coalescing operator `??`, which allows to express more precisely and more clearly what you mean. The semantics is:

```js
a ?? b // evaluates `a`. If `a` is null or undefined, evaluates `b`.
```

In your JSON example:

```js
var total = 0;

total += JSON.parse(JSON.stringify({ "value": 0/0 })).value ?? NaN;

Number.isNaN(total); // true. Hurray!
```

—Claude
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: a more consistent and stricter number converting function - Number.of()

T.J. Crowder-2
* If you know that your input is either a string or null/undefined (e.g., as the result of  `someHTMLElement.getAttribute('foo')`), you could use `Number.parseFloat()`, which will produce NaN for the empty string, null and undefined.

Of course, `Number.parseFloat("23.4ducky")` results in `23.4`. Duan indicated he/she wanted this `Number.of` to be more strict.

I, too, have wanted something *strict* that didn't convert `""` and `null` to `0`. (Like many, I suspect, I have one in my toolkit; but the idea of something in the standard library appeals.)

-- T.J. 

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: a more consistent and stricter number converting function - Number.of()

段垚
In reply to this post by Claude Pache

在 2017/2/24 20:08, Claude Pache 写道:

>> Le 24 févr. 2017 à 04:50, 段垚 <[hidden email]> a écrit :
>>
>> Hi,
>>
>>
>> Converting an arbitray value to a number in JS can be rather inconsistent and unexpected:
>>
>> * `null` and `undefined` are different: `+null === 0` but `+undefined` is NaN.
>>
>> * Empty string and non-nubmeric strings are different: `+"" === 0` but `+"foo"` is NaN.
>>
>>
>> This problem can be worse because JSON only support finite numbers:
>>
>> ```
>>
>> var total = 0;
>>
>> total += JSON.parse(JSON.stringify({ "value": 0/0 })).value;
>>
>> total === 0; //Oops, NaN is serialized as null, and then converted to 0
>>
>> ```
>>
>> So I propose a more consistent and stricter number converting function: `Number.of(value)`:
>>
>> 1. If `value` is `null` or `undefined`, return `NaN`;
>>
>> 2. If `value` is a number, return `value` itself;
>>
>> 3. If `value.valueOf()` returns a number, return that number, otherwise return `NaN`.
>>
>>
>> This means all non-number values except those have number type `.valueOf()` would be converted to NaN:
>>
>>
>> ```
>>
>> Number.of(null); // NaN
>>
>> Number.of(''); //NaN
>>
>> Number.of('1'); //NaN
>>
>>
>> var total = 0;
>>
>> total += Number.of(JSON.parse(JSON.stringify({ "value": 0/0 })).value);
>>
>> total; // NaN
>>
>> ```
>>
>>
>> What do you think?
>>
>>
>> Regards,
>>
>> Duan, Yao
>>
>
> Depending on the concrete situation, you might not need yet another way to convert into number.
>
> * If you know that your input is either a string or null/undefined (e.g., as the result of  `someHTMLElement.getAttribute('foo')`), you could use `Number.parseFloat()`, which will produce NaN for the empty string, null and undefined.

What I actually want is a function/operator that protect against
non-number values, including strings that can be parsed as numbers,
and objects whose `.toString()` happen to return strings can be parsed
as numbers.

>
> * If your issue is precisely with null/undefined, as it is the case in your JSON example, a more generic solution would be the null-coalescing operator `??`, which allows to express more precisely and more clearly what you mean. The semantics is:
>
> ```js
> a ?? b // evaluates `a`. If `a` is null or undefined, evaluates `b`.
> ```
>
> In your JSON example:
>
> ```js
> var total = 0;
>
> total += JSON.parse(JSON.stringify({ "value": 0/0 })).value ?? NaN;
>
> Number.isNaN(total); // true. Hurray!
> ```

The null-coalescing operator `??` is awosome and will solve my null/undefined issue.
However, it seems there is little progress since it was proposed ( https://esdiscuss.org/topic/proposal-for-a-null-coalescing-operator ).
Are there objections or simply lack of interest?

>
> —Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: a more consistent and stricter number converting function - Number.of()

Isiah Meadows-2
Most likely lack of interest and nobody trying to push it through the
process. It's come up repeatedly, but no one has actually tried to
write up a formal proposal and get someone on TC39 to champion it.
-----

Isiah Meadows
[hidden email]


On Fri, Feb 24, 2017 at 8:28 AM, 段垚 <[hidden email]> wrote:

>
> 在 2017/2/24 20:08, Claude Pache 写道:
>>>
>>> Le 24 févr. 2017 à 04:50, 段垚 <[hidden email]> a écrit :
>>>
>>> Hi,
>>>
>>>
>>> Converting an arbitray value to a number in JS can be rather inconsistent
>>> and unexpected:
>>>
>>> * `null` and `undefined` are different: `+null === 0` but `+undefined` is
>>> NaN.
>>>
>>> * Empty string and non-nubmeric strings are different: `+"" === 0` but
>>> `+"foo"` is NaN.
>>>
>>>
>>> This problem can be worse because JSON only support finite numbers:
>>>
>>> ```
>>>
>>> var total = 0;
>>>
>>> total += JSON.parse(JSON.stringify({ "value": 0/0 })).value;
>>>
>>> total === 0; //Oops, NaN is serialized as null, and then converted to 0
>>>
>>> ```
>>>
>>> So I propose a more consistent and stricter number converting function:
>>> `Number.of(value)`:
>>>
>>> 1. If `value` is `null` or `undefined`, return `NaN`;
>>>
>>> 2. If `value` is a number, return `value` itself;
>>>
>>> 3. If `value.valueOf()` returns a number, return that number, otherwise
>>> return `NaN`.
>>>
>>>
>>> This means all non-number values except those have number type
>>> `.valueOf()` would be converted to NaN:
>>>
>>>
>>> ```
>>>
>>> Number.of(null); // NaN
>>>
>>> Number.of(''); //NaN
>>>
>>> Number.of('1'); //NaN
>>>
>>>
>>> var total = 0;
>>>
>>> total += Number.of(JSON.parse(JSON.stringify({ "value": 0/0 })).value);
>>>
>>> total; // NaN
>>>
>>> ```
>>>
>>>
>>> What do you think?
>>>
>>>
>>> Regards,
>>>
>>> Duan, Yao
>>>
>>
>> Depending on the concrete situation, you might not need yet another way to
>> convert into number.
>>
>> * If you know that your input is either a string or null/undefined (e.g.,
>> as the result of  `someHTMLElement.getAttribute('foo')`), you could use
>> `Number.parseFloat()`, which will produce NaN for the empty string, null and
>> undefined.
>
>
> What I actually want is a function/operator that protect against non-number
> values, including strings that can be parsed as numbers,
> and objects whose `.toString()` happen to return strings can be parsed as
> numbers.
>
>>
>> * If your issue is precisely with null/undefined, as it is the case in
>> your JSON example, a more generic solution would be the null-coalescing
>> operator `??`, which allows to express more precisely and more clearly what
>> you mean. The semantics is:
>>
>> ```js
>> a ?? b // evaluates `a`. If `a` is null or undefined, evaluates `b`.
>> ```
>>
>> In your JSON example:
>>
>> ```js
>> var total = 0;
>>
>> total += JSON.parse(JSON.stringify({ "value": 0/0 })).value ?? NaN;
>>
>> Number.isNaN(total); // true. Hurray!
>> ```
>
>
> The null-coalescing operator `??` is awosome and will solve my
> null/undefined issue.
> However, it seems there is little progress since it was proposed (
> https://esdiscuss.org/topic/proposal-for-a-null-coalescing-operator ).
> Are there objections or simply lack of interest?
>
>
>>
>> —Claude
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss