【问题标题】:What's the difference between String(value) vs value.toString()String(value) 与 value.toString() 有什么区别
【发布时间】:2010-10-15 18:55:11
【问题描述】:

Javascript 有很多关于类型和类型转换的“技巧”,所以我想知道这两种方法是否相同,或者是否有一些极端情况使它们不同?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    它们并不完全相同,实际上the String constructor called as a function(你的第一个例子)最后会调用传递对象的toString方法,例如:

    var o = { toString: function () { return "foo"; } };
    String(o); // "foo"
    

    另一方面,如果一个标识符引用nullundefined,你不能使用toString方法,它会给你一个TypeError异常

    var value = null;
    String(null);     // "null"
    value.toString(); // TypeError
    

    作为函数调用的String 构造函数大致相当于:

    value + '';
    

    ObjectPrimitive的类型转换规则在规范中有详细描述,[[DefaultValue]]内部操作。

    简单总结一下,从ObjectString的转换,有以下几个步骤:

    1. 如果可用,请执行toString 方法。
      • 如果result原语,则返回result,否则转到步骤2。
    2. 如果可用,请执行valueOf 方法。
      • 如果result原语,则返回result,否则转到步骤3。
    3. 投掷TypeError

    鉴于以上规则,我们可以举例说明所涉及的语义:

    var o = {
      toString: function () { return "foo"; },
      valueOf:  function () { return "bar"; }
    };
    
    String(o); // "foo"
    
    // Make the toString method unavailable:
    o.toString = null;
    
    String(o); // "bar"
    
    // Also make the valueOf method unavailable:
    o.valueOf = null;
    
    try { 
      String(o); 
    } catch (e) {
      alert(e); // TypeError
    }
    

    如果您想了解有关此机制的更多信息,我建议您查看ToPrimitiveToString 内部操作。

    我也推荐阅读这篇文章:

    【讨论】:

    • 还有第三种“方式”,如果你在任何值上调用这个:new String(value),它总是会返回一个字符串对象。
    • @Herbertusz new String({toString: null}) 抛出 TypeError
    • 加上符号String()+ '' 现在有相当显着的区别。 String(Symbol()) 会运行,但 Symbol() + '' 会抛出一个错误(并且 Symbol() 会传递一个虚假的守卫,不像 null 和 undefined,所以 x && (x + '') 现在可以抛出)。
    • 看起来 null 没有 toString 和 valueOf 方法,但 String(null) 返回 'null' 而不会引发错误。特殊行为?
    【解决方案2】:

    如果value 为空或未定义,value.toString() 将导致错误。 String(value) 不应该。

    例如:

    var value = null;
    alert(value.toString());
    

    将失败,因为value == null

    var value = null;
    alert(String(value));
    

    应该显示一条消息“null”(或类似的),但它不会崩溃。

    【讨论】:

    • 我从未在 javascript 中看到过空指针异常...你在哪里看到的?
    • 不错。有一个例子会更好
    • @no, @casablanca 已修复。我习惯了Java。 @mykhal 看起来怎么样?
    • 它返回一个字符串 "null" :)
    【解决方案3】:

    String(value) 在任何情况下都应该与value.toString() 具有相同的结果,除了没有nullundefined 等属性的值。 ''+value 将产生相同的结果。

    【讨论】:

      【解决方案4】:

      String() [构造函数调用] 基本上是调用 .toString()

      .toString()String() 可以在原始值(数字、布尔值、字符串)上调用,基本上不会做任何特别的事情:

      真 => '真'

      假 => '假'

      17 => '17'

      '你好' =>'你好'

      但是在对象上调用这些函数才是有趣的地方:

      如果对象有它自己的 .toString() 函数,它将在您需要将此对象视为字符串时调用(显式/隐式)

      let obj = {
                 myName:"some object",
                 toString:function(){ return this.myName; } 
                }
      
      //implicitly treating this obj as a string
      "hello " + obj; //"hello some object"
      
      //OR (explicitly)
      "hello " + String(obj) //calling the existent toString function
      
      //OR
      "hello " + obj.toString(); //calling toString directly
      

      顺便说一句,如果你想将此对象视为一个数字,它应该有一个 .valueOf() 函数在其中定义。

      如果我们将两者都放在一个对象中会怎样?

      如果我们想将此对象视为字符串 => 使用 .toString()

      如果我们想将此对象视为数字 => 使用 .valueOf()

      如果我们只定义了 .valueOf() 会怎样?

      .valueOf() 定义在对象内部,无论我们想将对象作为字符串还是数字处理,都会被调用

      【讨论】:

        【解决方案5】:

        我刚刚在 ES6 上尝试过,发现要让String() 查看对象内部的valueOf(),对象必须有toString() 方法。如果对象没有toString(),那么无论是否有valueOf(),控制台都会返回'[object Object]'。所以在第一个“步骤”中,我们总是必须有toString(),否则String() 方法不会查看valueOf

        请检查:

        let obj = {
            name:'b',
            age:22,
            valueOf: function(){
                return 'heeee';
            }
        }
        
        String(obj); // prints '[object Object]'
        

        另一方面,

        let obj = {
            name:'b',
            age:22,
            toString:null,
            valueOf: function(){
                return 'heeee';
            }
        }
        String(obj); // prints 'heeee'
        

        let obj = {
          name: 'b',
          age: 22,
          valueOf: function() {
            return 'heeee';
          }
        }
        
        console.log(String(obj));
        
        let obj2 = {
          name: 'b',
          age: 22,
          toString: null,
          valueOf: function() {
            return 'heeee';
          }
        }
        
        console.log(String(obj2));

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-02-16
          • 1970-01-01
          • 1970-01-01
          • 2016-11-22
          • 2016-02-27
          • 2016-03-26
          • 2016-11-09
          相关资源
          最近更新 更多