美文网首页
valueof 和toString

valueof 和toString

作者: 209bd3bc6844 | 来源:发表于2018-01-18 11:00 被阅读0次

    var a = new String( "abc" );的值应当是什么。
    a是一个对象。一个基本类型值的封装对象。

    typeof    a; // 是"object",不是"String"
    a instanceof String; // true 
    Object.prototype.toString.call( a ); // "[object String]"
    

    通过构造函数(如 new String("abc"))创建出来的是封装了基本类型值(如 "abc")的封 装对象。
    我们比较准确的判断一个类型的方法为
    Object.prototype.toString(..)
    这是因为所有 typeof 返回值为 "object" 的对象,都有一个内部属性 [[Class]],这个属性无法直接访问,一般通过 Object.prototype.toString(..)来查看,一般对象的内部 [[Class]] 属性和创建该对象的内建原生构造函数相对应。除了null 和 undefined,因为
    Object.prototype.toString.call( null );    // "[object Null]"
    Object.prototype.toString.call( undefined );   // "[object Undefined]"
    

    虽然 Null() 和 Undefined() 这样的原生构造函数并不存在,但是内部 [[Class]] 属性值仍 然是 "Null" 和 "Undefined"。我们至少可以准确判断出类型。

    为什么 "abc" 可以有.length等属性?

    封装对象(object wrapper)扮演着十分重要的角色。由于基本类型值没有 .length 和 .toString() 这样的属性和方法,需要通过封装对象才能访问,此时 JavaScript 会自动为 基本类型值包装(box 或者 wrap)一个封装对象:

    一般情况下,我们不需要直接使用封装对象。最好的办法是让 JavaScript 引擎自己决定什 么时候应该使用封装对象。换句话说,就是应该优先考虑使用 "abc" 和 42 这样的基本类型 值,而非new String("abc")和new Number(42)。

    如果想要得到封装对象中的基本类型值,可以使用 valueOf() 函数:

         var a = new String( "abc" );
         var b = new Number( 42 );
         var c = new Boolean( true );
         a.valueOf(); // "abc"
         b.valueOf(); // 42
         c.valueOf(); // true
    

    在需要用到封装对象中的基本类型值的地方会发生隐式拆封。因为没有new Null()new Undefined()这样的封装器,也就是说他们是没有对应的封装对象。从而没有对应的valueOf()

    var str1 = 'w3cplus'; 
    var str2 = new String('w3cplus');
     typeof(str1); // => string 
    typeof(str2); // => object 
    str1 == str2 // => true
    
    

    str1是一个String类型,而str2却是一个Object类型,但用==比较两个变量时,结果却为true。这是因为,在JavaScript中会帮我们自动转换类型,然后再进行比对。

    String(),new String(), toString() 区别

    toString()String()的主要区别就在于
    String()还能转换nullundefined值,也可以说String()toString()增强版,在开发中直接使用String()似乎更好,这样能避免潜在的转换风险。

    toString()和valueOf()作用差不多,都是转换成原始类型的值。
    valueOf():返回最适合该对象类型的原始值;
    toString(): 将该对象的原始值以字符串形式返回。
    这两个方法一般是交由JS去隐式调用,以满足不同的运算情况。
    在数值运算里,会优先调用valueOf(),如a + b;
    在字符串运算里,会优先调用toString(),如alert(c)。
    在JavaScript进行对比或者各种运算的时候会把对象转换成Number、String、Boolean这些类型,从而进行后续的操作

    String转换

    在某个操作或者运算需要字符串的时候,往往会触发Object的String转换

    var obj={name:'Mofei'}
    var str = ' ' + obj
    console.log(str);  //   [object Object]
    

    上述的例子中,在字符串相加的过程中,系统调用了obj的String转换,具体规则如下:

    1. 如果toString方法存在并且返回“原始类型”,返回toString的结果。
    2. 如果toString方法不存在或者返回的不是“原始类型”,调用valueOf方法,如果valueOf方法存在,并且返回“原始类型”数据,返回valueOf的结果。
    3. 其他情况,抛出错误。
    Number转换

    当需要使用Number时,( 如Math.sin() )等,解释器会尝试将对象转换成Number对象。
    通常有如下的情况会触发Number转换

    1. 方法参数需要Number的时候,如Math.sin(obj)等
    2. 对比的时候,如 obj == 'abc'
    3. 运算的时候,如 obj + 123

    转换规则如下:

    1. 如果valueOf存在,且返回“原始类型”数据,返回valueOf的结果。
    2. 如果toString存在,且返回“原始类型”数据,返回toString的结果。
    3. 报错。
    Boolean转换

    在进行布尔比较的时候,比如 if(obj) , while(obj)等等,会进行布尔转换,布尔转换遵循如下规则:

    布尔值
    true/false true/false
    undefined,null false
    Number 0,NaN 对应 false, 其他的对应 true
    String ""对应false,其他对应true('0'对应的是true)
    Object true

    JavaScript 对象转换,toString,valueOf

    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 数字值,可以携带进制参数

    隐式数据转换即为解释器自发根据需要调用Number(),Boolean()等基本类型转换函数使结果符合期待。若参数为object类型时,调用ToPrimitive()(假想函数),该函数根据需要的数据类型做出的反应也不同,若在使用操作符运算时需要number类型则优先调用valueOf(),结果为NaN再调用toString()。其他大部分情况需要string类型则优先调用toString()。

    toString()和valueOf()的主要不同点在于

    1、 toString()返回的是字符串,而valueOf()返回的是基本类型值

    2、由于undefined和null不是对象,所以它们toString()和valueOf()两个方法都没有

    3、数值Number类型的toString()方法可以接收转换基数,返回不同进制的字符串形式的数值;而valueOf()方法无法接受转换基数

    4、时间Date类型的toString()方法返回的表示时间的字符串表示;而valueOf()方法返回的是现在到1970年1月1日00:00:00的数值类型的毫秒数

    5、包装对象的valueOf()方法返回该包装对象对应的原始值

    6、使用toString()方法可以区分内置函数和自定义函数

    如果只重写了toString,对象转换时会无视valueOf的存在来进行转换。如果只重写了valueOf方法,在要转换为字符串的时候会优先考虑toString方法。在不能调用toString的情况下,只能让valueOf上阵了。

    相关文章

      网友评论

          本文标题:valueof 和toString

          本文链接:https://www.haomeiwen.com/subject/gvernxtx.html