161 lines
4.3 KiB
JavaScript
161 lines
4.3 KiB
JavaScript
/**
|
|
* @file Converts argument to a value of type Number.
|
|
* @version 2.0.0
|
|
* @author Xotic750 <Xotic750@gmail.com>
|
|
* @copyright Xotic750
|
|
* @license {@link <https://opensource.org/licenses/MIT> MIT}
|
|
* @module to-number-x
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var cachedCtrs = require('cached-constructors-x');
|
|
var castNumber = cachedCtrs.Number;
|
|
var Rx = cachedCtrs.RegExp;
|
|
var toPrimitive = require('to-primitive-x');
|
|
var libTrim = require('trim-x');
|
|
var trim2016 = libTrim.trim2016;
|
|
var trim2018 = libTrim.trim2018;
|
|
var libParseInt = require('parse-int-x');
|
|
var $parseInt2016 = libParseInt.parseInt2016;
|
|
var $parseInt2018 = libParseInt.parseInt2018;
|
|
var pStrSlice = cachedCtrs.String.prototype.slice;
|
|
var NAN = require('nan-x');
|
|
|
|
var binaryRegex = /^0b[01]+$/i;
|
|
// Note that in IE 8, RegExp.prototype.test doesn't seem to exist: ie, "test" is
|
|
// an own property of regexes. wtf.
|
|
var test = binaryRegex.test;
|
|
var isBinary = function _isBinary(value) {
|
|
return test.call(binaryRegex, value);
|
|
};
|
|
|
|
var octalRegex = /^0o[0-7]+$/i;
|
|
var isOctal = function _isOctal(value) {
|
|
return test.call(octalRegex, value);
|
|
};
|
|
|
|
var nonWSregex2016 = new Rx('[\u0085\u200b\ufffe]', 'g');
|
|
var hasNonWS2016 = function _hasNonWS(value) {
|
|
return test.call(nonWSregex2016, value);
|
|
};
|
|
|
|
var nonWSregex2018 = new Rx('[\u0085\u180e\u200b\ufffe]', 'g');
|
|
var hasNonWS2018 = function _hasNonWS(value) {
|
|
return test.call(nonWSregex2018, value);
|
|
};
|
|
|
|
var invalidHexLiteral = /^[-+]0x[0-9a-f]+$/i;
|
|
var isInvalidHexLiteral = function _isInvalidHexLiteral(value) {
|
|
return test.call(invalidHexLiteral, value);
|
|
};
|
|
|
|
var $toNumber2016 = function toNumber2016(argument) {
|
|
var value = toPrimitive(argument, Number);
|
|
if (typeof value === 'symbol') {
|
|
throw new TypeError('Cannot convert a Symbol value to a number');
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
if (isBinary(value)) {
|
|
return toNumber2016($parseInt2016(pStrSlice.call(value, 2), 2));
|
|
}
|
|
|
|
if (isOctal(value)) {
|
|
return toNumber2016($parseInt2016(pStrSlice.call(value, 2), 8));
|
|
}
|
|
|
|
if (hasNonWS2016(value) || isInvalidHexLiteral(value)) {
|
|
return NAN;
|
|
}
|
|
|
|
var trimmed = trim2016(value);
|
|
if (trimmed !== value) {
|
|
return toNumber2016(trimmed);
|
|
}
|
|
}
|
|
|
|
return castNumber(value);
|
|
};
|
|
|
|
var $toNumber2018 = function toNumber2018(argument) {
|
|
var value = toPrimitive(argument, Number);
|
|
if (typeof value === 'symbol') {
|
|
throw new TypeError('Cannot convert a Symbol value to a number');
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
if (isBinary(value)) {
|
|
return toNumber2018($parseInt2018(pStrSlice.call(value, 2), 2));
|
|
}
|
|
|
|
if (isOctal(value)) {
|
|
return toNumber2018($parseInt2018(pStrSlice.call(value, 2), 8));
|
|
}
|
|
|
|
if (hasNonWS2018(value) || isInvalidHexLiteral(value)) {
|
|
return NAN;
|
|
}
|
|
|
|
var trimmed = trim2018(value);
|
|
if (trimmed !== value) {
|
|
return toNumber2018(trimmed);
|
|
}
|
|
}
|
|
|
|
return castNumber(value);
|
|
};
|
|
|
|
module.exports = {
|
|
/**
|
|
* reference to toNumber2018.
|
|
*/
|
|
toNumber: $toNumber2018,
|
|
|
|
/**
|
|
* This method converts argument to a value of type Number. (ES2016)
|
|
|
|
* @param {*} argument - The argument to convert to a number.
|
|
* @throws {TypeError} - If argument is a Symbol or not coercible.
|
|
* @returns {*} The argument converted to a number.
|
|
* @example
|
|
* var toNumber = require('to-number-x').toNumber2016;
|
|
*
|
|
* toNumber('1'); // 1
|
|
* toNumber(null); // 0
|
|
* toNumber(true); // 1
|
|
* toNumber('0o10'); // 8
|
|
* toNumber('0b10'); // 2
|
|
* toNumber('0xF'); // 16
|
|
*
|
|
* toNumber(' 1 '); // 1
|
|
*
|
|
* toNumber(Symbol('')) // TypeError
|
|
* toNumber(Object.create(null)) // TypeError
|
|
*/
|
|
toNumber2016: $toNumber2016,
|
|
|
|
/**
|
|
* This method converts argument to a value of type Number. (ES2018)
|
|
|
|
* @param {*} argument - The argument to convert to a number.
|
|
* @throws {TypeError} - If argument is a Symbol or not coercible.
|
|
* @returns {*} The argument converted to a number.
|
|
* @example
|
|
* var toNumber = require('to-number-x').toNumber2018;
|
|
*
|
|
* toNumber('1'); // 1
|
|
* toNumber(null); // 0
|
|
* toNumber(true); // 1
|
|
* toNumber('0o10'); // 8
|
|
* toNumber('0b10'); // 2
|
|
* toNumber('0xF'); // 16
|
|
*
|
|
* toNumber(' 1 '); // 1
|
|
*
|
|
* toNumber(Symbol('')) // TypeError
|
|
* toNumber(Object.create(null)) // TypeError
|
|
*/
|
|
toNumber2018: $toNumber2018
|
|
};
|