首页 > 解决方案 > 当值既不是数字也不是字符串类型时,Number() 是否显式调用 toString()?(例如功能)

问题描述

由于文档描述了 parseInt() 的这种行为,但没有描述作为函数调用的 Number() 构造函数,我正在寻找一些关于这是否可靠以及是否有来自官方来源的引用的见解。示例代码:

let adder = (function () {
    let sum = 0

    return function add(num) {
        sum += num
        add.toString = () => sum //method is overwritten to return value
        return add
    }
})()

console.log(Number(adder(5)(2)(3))) // => 10

标签: javascriptfunction

解决方案


请参阅规范。调用NumberToNumeric(value)使用参数调用,它将使用参数调用 ToPrimitive,它将(通常) 使用参数和提示调用OrdinaryToPrimitivenumber,它会:

  1. 断言:类型(O)是对象。
  2. 断言:提示是字符串或数字。
  3. 如果提示是字符串,则
    1. 让 methodNames 为 « "toString", "valueOf" »。
  4. 别的,
    1. 让 methodNames 为 « "valueOf", "toString" »。
  5. 对于 methodNames 的每个元素名称,执行
    1. 让方法是?获取(O,名称)。
    2. 如果 IsCallable(method) 为真,则
      1. 让结果是?调用(方法,O)。
      2. 如果 Type(result) 不是 Object,则返回结果。
  6. 抛出 TypeError 异常。

因此,在将对象转换为数字基元的情况下,将首先尝试调用valueOf对象上的方法(如果存在)。如果这样的方法不存在,它将尝试调用toString对象上的方法。

是的,依靠在不存在toString的情况下被调用是可靠的。valueOf

说明如何首先调用的实时代码段valueOf(如果存在):

let adder = (function () {
    let sum = 0

    return function add(num) {
        sum += num
        add.toString = () => {
            console.log('toString called');
            return sum; //method is overwritten to return value
        };
        add.valueOf = () => {
            console.log('valueOf called');
            return sum; //method is overwritten to return value
        };
        return add
    }
})()

console.log(Number(adder(5)(2)(3))) // => 10

如果对象没有自己的toStringor属性valueOfObject.prototype.toString将被调用,导致[object Object]- 但这不会被强制转换为数字,导致NaN.

let adder = (function () {
    let sum = 0

    return function add(num) {
        sum += num
        return add
    }
})()

console.log(Number(adder(5)(2)(3))) // => 10

如果该对象不继承自其原型链中的任何位置,Object.prototype也没有toString任何valueOf地方,则会引发错误:

let adder = Object.create(null);

console.log(Number(adder))


推荐阅读