我试图理解这种行为:
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
有人可以对此有所了解吗?
答案 0 :(得分:4)
演练:
在添加之前,左侧和右侧都有值
二进制操作的转换为基元(string
或number
)。
根据值的上下文,可能会提供一个“提示”,表明它应该成为哪种原始类型。
如果未提供提示,则默认为其首选类型。除Object
之外,所有number
的首选类型均为Date
,string
更喜欢{{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。