Last Surprise Lyn
  1. 1 Last Surprise Lyn
  2. 2 One Last You Jen Bird
  3. 3 かかってこいよ NakamuraEmi
  4. 4 Life Will Change Lyn
  5. 5 The Night We Stood Lyn
  6. 6 Quiet Storm Lyn
  7. 7 Flower Of Life 发热巫女
  8. 8 Time Bomb Veela
  9. 9 Libertus Chen-U
  10. 10 Hypocrite Nush
  11. 11 Warcry mpi
2016-12-27 23:17:46

从valueOf()和toString()谈JavaScript隐式类型转换

首先需要知道一点,valueOf和toString函数通常不会显式调用,一般调用时机都是当语句执行时,如果数据类型不符合期待,解释器自动执行帮助我们完成类型转换(通常作用于object对象)。接下来首先根据不同情况分析隐式类型转换规则。

先看一段stackoverflow上的代码示例。

var x = {
    toString: function () { return "foo"; },
    valueOf: function () { return 42; }
};

alert(x); // foo
"x=" + x; // "x=42"
x + "=x"; // "42=x"
x + "1"; // 421
x + 1; // 43
["x=", x].join(""); // "x=foo"

我们重写了对象的toString和valueOf方法,可以看出执行不同语句时,分别隐式调用了这两个方法,那么分别适用于什么情况呢?不妨对这些代码做一个分类来讨论。

1.操作符

当操作符作用于数值计算时

  • 基本数据类型会隐式调用Number()转换为数值进行计算
  • 对象会先调用valueOf()取得操作数,如果运算结果为NaN则再调用toString()

大多数操作符为这种类型。而加性操作符中存在一个特例情况,当两个操作数执行加法计算时,如果存在一个操作数为字符串,则对所有操作数执行toString()函数进行转换然后进行拼接操作。伪代码解释如下:

    a + b:
    pa = ToPrimitive(a)
    pb = ToPrimitive(b)
    if(pa is string || pb is string)
       return concat(ToString(pa), ToString(pb))
    else
       return add(ToNumber(pa), ToNumber(pb))

toPrimitive是通过valueOf将数据转化为基本数据类型,若得到基本数据类型则结束,否则调用toString的假想函数。


2.语句

  • 当需要利用布尔值进行判断时,会自动调用Boolean()转换表达式结果
  • 当alert输出时,优先调用toString()
  • 当以[x]形式进行属性访问时,优先调用toString()

综合以上,根据我的理解总结出: 隐式数据转换即为解释器自发根据需要调用Number(),Boolean()等基本类型转换函数使结果符合期待。若参数为object类型时,调用ToPrimitive()(假想函数),该函数根据需要的数据类型做出的反应也不同,若在使用操作符运算时需要number类型则优先调用valueOf(),结果为NaN再调用toString()。其他大部分情况需要string类型则优先调用toString()。这两种方法都可以重写,附原生方法参考。


valueOf()原生实现

数据类型 返回值
Array 与 Array.toString 和 Array.join 方法相同
Function 函数本身
Date 毫秒数UTC
Boolean 布尔值
Number 数字值
String 字符串值
Object 对象本身

toString()原生实现

数据类型 返回值
Array 与 Array.valueOf 和 Array.join 方法相同
Function 获取函数源代码
Object 返回[object type]
Boolean 布尔值
Date 格式化日期
String 字符串值
Number 数字值,可以携带进制参数

-- EOF --

添加在分类「 前端开发 」下,并被添加 「JavaScript」 标签。