/** * @file Converts argument to a value of type Number. * @version 2.0.0 * @author Xotic750 * @copyright Xotic750 * @license {@link 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 };