请解释为什么以及如何+新的Date(); 在IE8或更低版本中作为Date.now()的"解决方法"

Jan*_*ray 36 javascript

(我正在阅读" 面向Web开发人员的专业JavaScript "一书,以提供有关此问题的背景信息,特别是第5章"参考类型")

我想知道为什么以及如何 var start = +new Date();将当前的毫秒表示作为解决方案(例如:IE8)的解决方案,以支持ECMAScript 5 Date.now()

+与仅仅是普通的旧的相比,这里的运营商做了什么new Date()呢?

and*_*toi 57

会发生什么是您首先创建一个新的Date对象,然后将其强制转换为数字.

TL; DR-版本

在引擎盖下,运行时调用对象的valueOf方法Date.

详细版本

返回一个新Date对象

var d = new Date;
Run Code Online (Sandbox Code Playgroud)

使用一元+运算符

var n = +d;
Run Code Online (Sandbox Code Playgroud)

一元+运算符调用内部ToNumberd.

9.3 ToNumber

采用输入参数,如果参数类型Object(Date is),使用input提示Number调用内部ToPrimitive.

9.1 ToPrimitive

获取输入参数和可选参数PreferredType.

如果输入类型是Object,那么规范说:

返回Object的默认值.通过调用对象的[[DefaultValue]]内部方法,传递可选提示PreferredType来检索对象的默认值.对于8.12.8中的所有本机ECMAScript对象,此规范定义了[[DefaultValue]]内部方法的行为 .

8.12.8 [[DefaultValue]](提示)

当使用提示号调用O的[[DefaultValue]]内部方法时,将执行以下步骤:

  1. 设valueOf是使用参数"valueOf"调用对象O的[[Get]]内部方法的结果.
  2. 如果IsCallable(valueOf)为真,那么,
    1. 设val是调用valueOf的[[Call]]内部方法的结果,其中O为此值和空参数列表.
    2. 如果val是原始值,则返回val.

在代码中,这大致转换为:

var val,
    type,
    valueOf = O.Get( 'valueOf' );

if ( typeof valueOf === 'function' ) {
    val = valueOf.call( O );
    type = typeof val;
    if ( val == null || type === 'boolean' || type === 'number' || type === 'string' ) {
        return val;
    }
}
Run Code Online (Sandbox Code Playgroud)

[[Get]]使用参数"valueOf"来表示O的内部方法基本上意味着返回Date.prototype.valueOf.

15.9.5.8 Date.prototype.valueOf()

valueOf函数返回一个Number,即此时间值.

如果我们现在回到9.3 ToNumber,我们看到ToNumber调用自己,这次是val8.12.8 [[DefaultValue]](提示)返回primValue.如果参数类型为Number,则表示:

结果等于输入参数(无转换).

结束

  • "秘密valueOf()"成就解锁! (6认同)

mr.*_*fox 7

IE上的Date.now()函数:

return a number of milliseconds between midnight, January 1, 1970, and the current date and time.
Run Code Online (Sandbox Code Playgroud)

要求

Not supported in installed versions earlier than Internet Explorer 9. However, it is supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards, Internet Explorer 9 standards, Internet Explorer 10 standards. Also supported in Windows Store apps.
Run Code Online (Sandbox Code Playgroud)

要获取IE8上的当前Date对象,您可以使用:

if (typeof Date.now() === 'undefined') {
  Date.now = function () { 
      return new Date(); 
  }
}
Run Code Online (Sandbox Code Playgroud)

对于IE8上的日期对象中的获取时间值(自1970年1月1日午夜以来的毫秒数),您可以使用:

var currentDateTime = +new Date(); 
Run Code Online (Sandbox Code Playgroud)

  • 这个答案实际上会导致IE8和之前的问题,因为`Date.now`将是未定义的,因此尝试将其作为`Date.now()`调用会导致错误.但是,执行以下操作非常容易:```if(typeof Date.now ==='undefined'){Date.now = function(){return + new Date(); ```` (2认同)

Sjo*_*erd 6

一元运算+ 将值转换为数字.例如,+"123"将字符串转换"123"为数字123.这也适用于日期,转换为数字的日期给出了毫秒数.