为什么Date添加会产生字符串?

时间:2016-03-15 13:51:18

标签: javascript

我试图理解这种行为:

var d = new Date();

console.log(+d); // 1458049171381
console.log(1 + d); // '1Tue Mar 15 2016 09:39:31 GMT-0400 (EDT)'

与之相反:

var obj = {
  valueOf: function () {
    return 123;
  }
};

console.log(+obj); // 123
console.log(1 + obj); // 124

Date返回string时,为什么Date.prototype.valueOf添加结果为number

以下是Addition Operator's spec与JavaScript

的简单翻译
function ToPrimitive(x) {
  return x.valueOf();
}

function IsString(x) {
  return typeof x === 'string';
}

function ToString(x) {
  return x.toString();
}

function ToNumber(x) {
  try {
    return parseFloat(x);
  } catch (e) {
    return NaN;
  }
}

function AdditionOperator(lval, rval) {

  let lprim = ToPrimitive(lval);
  let rprim = ToPrimitive(rval);

  if (IsString(lprim) || IsString(rprim)) {
    return ToString(lprim) + ToString(rprim);
  } else {
    return ToNumber(lprim) + ToNumber(rprim);
  }
}

但是,如果我使用Date对象调用它,它将返回一个数值:

AdditionOperator(new Date(), 1) // 1458049347088

有人可以对此有所了解吗?

1 个答案:

答案 0 :(得分:4)

演练:

  • 在添加之前,左侧和右侧都有值 二进制操作的转换为基元(stringnumber)。

  • 根据值的上下文,可能会提供一个“提示”,表明它应该成为哪种原始类型。

  • 如果未提供提示,则默认为其首选类型。除Object之外,所有number的首选类型均为Datestring更喜欢{{1}}(并且会让所有人感到困惑)。

根据spec

  

除Date对象之外的所有标准对象都处理没有提示   好像给出了提示号码;日期对象处理缺少a   提示就好像给出了提示字符串一样。异国情调的物体可以处理   没有其他方式的提示。

如果是Date,他们会exception

  

在本规范中定义的对象中只有Date对象(参见   20.3.4.45)和Symbol对象(见19.4.3.4)覆盖了默认的ToPrimitive行为。日期对象不像提示那样处理任何提示   字符串。

另外,请检查this

  

ECMAScript语言运算符调用此函数来转换   日期对象为原始值。提示的允许值是   “default”,“number”和“string”。日期对象是唯一的   内置ECMAScript对象,因为它们将“默认”视为存在   相当于“string”,所有其他内置的ECMAScript对象都可以处理   “默认”等同于“数字”。

因此,Date仅用作String。