• [译]JavaScript中,如何将一个值转换为字符串


    原文:http://www.2ality.com/2012/03/converting-to-string.html


    译者注:前两天在看ES5的时候顺便出了一道题,今天看到这篇文章,刚好解释的很清楚,就翻译了一下.

    在JavaScript中,主要有三种方法能让任意值转换为字符串.本文讲解了每种方法以及各自的优缺点.

    1.转换字符串的三种方法

    这三种将value转换为字符串的方法是:

    1. value.toString()
    2. "" + value
    3. String(value)

    第一种方法存在的问题是,它不能把null和undefined转换为字符串.还有第二种和第三种方法,这两种方法的效果基本一样.

    • ""+value: 使用加法运算符配合一个空字符串可以把任意值转换为字符串,我觉得这种方法代码的可读性很差,但相对String(value)来,还是有一些人更喜欢用这种转换方式.
    • String(value): 这种方法可读性更好,唯一的问题是,这种函数调用可能会迷惑一些人,尤其是那些熟悉Java的的程序员,因为String同时也是一个构造函数.要注意的是它作为普通函数和作为构造函数时的表现完全不同:
    > String("abc") === new String("abc")
    false
    
    > typeof String("abc")
    'string'
    > String("abc") instanceof String
    false
    
    > typeof new String("abc")
    'object'
    > new String("abc") instanceof String
    true

    String作为普通函数时会产生一个字符串(一个原始值).作为构造函数时会产生一个String对象的实例.后者在JavaScript中很少用到,所以基本上你可以忽略掉String作为构造函数的用法,但一定要记得它是个转换函数.

    2.""+value 和 String(value)的细微差别

    到现在你已经知道了+String()都可以将它们的“参数”转换为字符串.但他们的转换方式还是着有细微的差别,不过几乎所有的情况下,转换结果都是一样的.

    2.1 将原始值转换为字符串

    这两种方法都是使用引擎内部的ToString()操作将原始值转换为字符串的.“内部操作”的意思是:这个操作函数是在ECMAScript 5.1 (§9.8)中定义的,但ES语言本身并不能访问到它.下面这个表格解释了ToString()是如何转换原始值的.

    参数 结果
    undefined "undefined"
    null "null"
    布尔值 "true"或者"false"
    数字 数字作为字符串,比如"1.765"
    字符串 无需转换

    2.2 将对象值转换为字符串

    这两种方法都先将对象值转换为原始值,然后再将原始值转换为字符串.但是在这个转换中, + 使用的是内部的ToPrimitive(Number)操作(除非被转换的是date对象),而String()用的是ToPrimitive(String).

    • ToPrimitive(Number): 将一个对象值转换为原始值,首先调用obj.valueOf().如果返回值是一个原始值,则返回这个原始值.如果不是,则再调用obj.toString().如果返回值是个原始值,返回这个原始值.否则,抛出TypeError异常.
    • ToPrimitive(String): 和上面的方法类似,只是优先调用obj.toString()方法而不是obj.valueOf().

    通过转换下面的这个对象,你可以看到它们之间的差别:

    var obj = {
        valueOf: function () {
            console.log("valueOf");
            return {}; // 不是原始值,继续执行
        },
        toString: function () {
            console.log("toString");
            return {}; // 不是原始值,继续执行
        }
    };  
    
    //运行:
    
    > "" + obj
    valueOf
    toString
    TypeError: Cannot convert object to primitive value
    
    > String(obj)
    toString
    valueOf
    TypeError: Cannot convert object to primitive value

    2.3 结果通常都相同

    上面讲的区别,在实际情况中几乎不太可能遇到.因为:大部分对象都使用了默认的继承而来的valueOf()方法,返回值总是这个对象本身.

    > var x = {}
    > x.valueOf() === x
    true

    因此, ToPrimitive(Number)通常会跳过valueOf方法返回toString()方法的返回值,这就表现的和ToPrimitive(String)完全一样.但是,如果这个对象是Boolean,Number或者String的对象实例,那么它的valueOf()会返回一个原始值(被这个对象包装前的原始值).那么这两种操作就会按照如下步骤执行:

    • ToPrimitive(Number)返回了对象的valueOf()方法的返回值(被包装前的原始值)再经过ToString()操作后的结果.
    • ToPrimitive(String)返回了对象的toString()方法的返回值(在该对象被包装前的原始值上进行ToString()操作的返回值).

    就这样,他们还是返回了相同的结果,只是转换的途径不同.

    3.结论

    你应该选择哪种方式来将其他类型的值转换为字符串呢?如果你能确保这个值永远不会是null或者undefined,则可以用value.toString()来转换.否则,""+valueString(value)选哪个都可以,看个人喜好,我认为String(value) 更明确一点.

    4.相关文章

    1. JavaScript values: not everything is an object [原始值和对象值的区别]
    2. [译]JavaScript中,{}+{}等于多少? [解释了+运算符的工作原理]
    3. String concatenation in JavaScript [怎样才能更好的连接多个字符串]
  • 相关阅读:
    访问者模式
    解释器模式
    享元模式
    职责链模式
    中介者模式
    单例模式
    桥接模式
    命令模式
    迭代器模式
    Python 学习笔记15 类
  • 原文地址:https://www.cnblogs.com/ziyunfei/p/2691062.html
Copyright © 2020-2023  润新知