Javascript JS valueOf和toString

Javascript JS valueOf和toString,javascript,tostring,Javascript,Tostring,在x中正在进行的魔法是什么,而在y中没有 var x = new Date; var y = { toString: function() { return x.toString(); }, valueOf: function() { return x.valueOf(); } }; String(x) // "Mon Mar 23 2015 18:26:40 GMT+0000 (GMT)" String(y) // "Mon M

x
中正在进行的魔法是什么,而在
y
中没有

var x = new Date;
var y = {
    toString: function() {
        return x.toString();
    },
    valueOf: function() {
        return x.valueOf();
    }
};

String(x) // "Mon Mar 23 2015 18:26:40 GMT+0000 (GMT)"
String(y) // "Mon Mar 23 2015 18:26:40 GMT+0000 (GMT)"
'' + x    // "Mon Mar 23 2015 18:26:40 GMT+0000 (GMT)"
'' + y    // "1427135200422"
我是否正确地认为
x
有一个primative值
ToString
s作为日期字符串,但是
y
没有primative值

编辑:

为了实现它的价值,以下工作(此处为ES6)是否有效:


根据规范第8.12.8节:

当在没有提示的情况下调用O的[[DefaultValue]]内部方法时,它的行为就像提示是数字一样,除非O是日期对象(参见15.9.6),在这种情况下,它的行为就像提示是字符串一样


+
操作符传递“PreferredType”提示,其行为就像没有提示一样(尽管规范没有很好地解释这一点,或者如果有,我找不到)。因此,您的
x
对象“首选”其字符串表示,而
y
对象使用数字表示。

中定义了
+
的行为

生产AdditiveExpression:AdditiveExpression
+
乘法表达式的计算方法如下:

  • 让lref是计算AdditiveExpression的结果
  • 让lval成为(lref)
  • 让rref是计算乘法表达式的结果
  • 设rval为(rref)
  • 让lprim成为(lval)
  • 设rprim为(rval)
  • 如果(lprim)是String或(rprim)是String,则
  • 返回串接(lprim)后接(rprim)的结果字符串
  • 返回将加法运算应用于(lprim)和(rprim)的结果。见下面的注释
  • 注1-在步骤5中对的调用中未提供任何提示 六,。除日期对象外的所有本机ECMAScript对象都处理 没有提示,就好像给出了提示编号一样;日期对象 处理没有提示的情况,就像给出提示字符串一样。主办 对象可以用其他方式处理没有提示的情况

    因此,根据和的定义

    • ToPrimitive为
      x
      返回
      x.toString()
      ,因为
      x
      是一个日期对象,所以它就像提示是字符串一样

    • ToPrimitive为
      y
      返回
      y.valueOf()
      ,因为
      y
      是一个非日期的本机对象,所以它就像提示是数字一样


    因此,加法运算符返回不同的结果。

    它仅在加法运算符步骤之后的“注释1”中明确表示:“在步骤5和6中对TopPrimitive的调用中未提供任何提示。”奇怪
    0+x
    给出一个字符串,
    0-x
    给出一个数字。@apsillers啊,好的;我在查看
    [[ToPrimitive]]
    部分的图表。@user2195592这是因为
    +
    操作符和
    -
    操作符有不同的行为。
    +
    操作符兼作字符串连接操作符,而
    -
    操作符总是数字减法。等等,为什么它是
    x.toString()
    ?@user2195592,因为
    x
    是一个日期实例,这就是规范在
    注释1
    中所说的。我现在明白了。谢谢
    var y = {
        [Symbol.toPrimitive](...args) {
            return x[Symbol.toPrimitive](...args);
        }
    };