Please explain why and how +new Date(); works as 'workaround' for Date.now() in IE8 or below

后端 未结 3 1146
眼角桃花
眼角桃花 2021-01-30 21:35

(I\'m reading the book \"Professional JavaScript for Web Developers\" to give a context about this question, specifically Chapter 5 on Reference Types)

I\'m wo

3条回答
  •  無奈伤痛
    2021-01-30 21:57

    What happens is that you first create a new Date object and then cast it to a number.

    TL;DR-version

    Under the hood the runtime calls valueOf method of the Date object.

    Verbose-version

    return a new Date object

    var d = new Date;
    

    use the Unary + Operator

    var n = +d;
    

    The unary + operator calls the internal ToNumber with d.

    9.3 ToNumber

    Takes an input argument and if the argument type is Object (Date is) call the internal ToPrimitive with input and hint Number.

    9.1 ToPrimitive

    takes an input argument and an optional argument PreferredType.

    if input type is Object the spec says:

    Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

    8.12.8 [[DefaultValue]] (hint)

    When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:

    1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".
    2. If IsCallable(valueOf) is true then,
      1. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
      2. If val is a primitive value, return val.

    In code this approximately translates to:

    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;
        }
    }
    

    [[Get]]ting the internal method of O with argument "valueOf" basically means returning Date.prototype.valueOf.

    15.9.5.8 Date.prototype.valueOf ( )

    The valueOf function returns a Number, which is this time value.

    If we now go back to 9.3 ToNumber we see that ToNumber calls itself, this time with the returned val from 8.12.8 [[DefaultValue]] (hint) as primValue. If argument type is Number it says:

    The result equals the input argument (no conversion).

    The End

提交回复
热议问题