美文网首页JavaScript
[JavaScript] WTFJS

[JavaScript] WTFJS

作者: 何幻 | 来源:发表于2017-08-09 17:50 被阅读103次

    1. Non-coercible objects

    function nonCoercible(val) {
      if (val == null) {
        throw TypeError('nonCoercible should not be called with null or undefined')
      }
    
      const res = Object(val)
    
      res[Symbol.toPrimitive] = () => {
        throw TypeError('Trying to coerce non-coercible object')
      }
    
      return res
    }
    
    // objects
    const foo = nonCoercible({foo: 'foo'})
    
    foo * 10      // -> TypeError: Trying to coerce non-coercible object
    foo + 'evil'  // -> TypeError: Trying to coerce non-coercible object
    
    // strings
    const bar = nonCoercible('bar')
    
    bar + '1'                 // -> TypeError: Trying to coerce non-coercible object
    bar.toString() + 1        // -> bar1
    bar === 'bar'             // -> false
    bar.toString() === 'bar'  // -> true
    bar == 'bar'              // -> TypeError: Trying to coerce non-coercible object
    
    // numbers
    const baz = nonCoercible(1)
    
    baz == 1             // -> TypeError: Trying to coerce non-coercible object
    baz === 1            // -> false
    baz.valueOf() === 1  // -> true
    

    ToPrimitive ( input [ , PreferredType ] )

    1. Assert: input is an ECMAScript language value.
    2. If Type(input) is Object, then
      2.a If PreferredType was not passed, let hint be "default".
      2.b Else if PreferredType is hint String, let hint be "string".
      2.c Else PreferredType is hint Number, let hint be "number".
      2.d Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
      2.e If exoticToPrim is not undefined, then
      2.e.(1) Let result be ? Call(exoticToPrim, input, « hint »).
      2.e.(2) If Type(result) is not Object, return result.
      2.e.(3) Throw a TypeError exception.
      2.f If hint is "default", set hint to "number".
      2.g Return ? OrdinaryToPrimitive(input, hint).
    3. Return input.

    OrdinaryToPrimitive ( O, hint )

    1. Assert: Type(O) is Object.
    2. Assert: Type(hint) is String and its value is either "string" or > "number".
    3. If hint is "string", then
      3.a Let methodNames be « "toString", "valueOf" ».
    4. Else,
      4.a Let methodNames be « "valueOf", "toString" ».
    5. For each name in methodNames in List order, do
      5.a Let method be ? Get(O, name).
      5.b If IsCallable(method) is true, then
      5.b.(1) Let result be ? Call(method, O).
      5.b.(2) If Type(result) is not Object, return result.
    6. Throw a TypeError exception.

    6.1.5.1 Well-Known Symbols
    19.4.2.12 Symbol.toPrimitive

    7.1.1 ToPrimitive ( input [ , PreferredType ] )
    7.1.3 ToNumber ( argument )
    7.1.12ToString ( argument )

    2. try ... finally

    (() => {
      try {
        return 2;
      } finally {
        return 3;
      }
    })();    // 3
    

    TryStatement : try Block Catch Finally

    1. Let B be the result of evaluating Block.
    2. If B.[[Type]] is throw, let C be CatchClauseEvaluation of Catch with parameter B.[[Value]].
    3. Else, let C be B.
    4. Let F be the result of evaluating Finally.
    5. If F.[[Type]] is normal, set F to C.
    6. Return Completion(UpdateEmpty(F, undefined)).

    13.15.8 Runtime Semantics: Evaluation

    3. Labelled statements

    foo: {
      console.log('first');
      break foo;
      console.log('second');
    }    // first
    
    foo:{
      while(true){
        break foo;
      }
      console.log(1);
    }
    console.log(2);    // 2
    

    A Statement may be prefixed by a label. Labelled statements are only used in conjunction with labelled break and continue statements. ECMAScript has no goto statement.

    13.13 Labelled Statements

    4. Arithmetics

    3  - 1  // -> 2
     3  + 1  // -> 4
    '3' - 1  // -> 2
    '3' + 1  // -> '31'
    
    '' + '' // -> ''
    [] + [] // -> ''
    {} + [] // -> 0
    [] + {} // -> '[object Object]'
    {} + {} // -> '[object Object][object Object]'
    
    '222' - -'111' // -> 333
    
    [4] * [4]       // -> 16
    [] * []         // -> 0
    [4, 4] * [4, 4] // NaN
    

    AdditiveExpression : AdditiveExpression + MultiplicativeExpression

    1. Let lref be the result of evaluating AdditiveExpression.
    2. Let lval be ? GetValue(lref).
    3. Let rref be the result of evaluating MultiplicativeExpression.
    4. Let rval be ? GetValue(rref).
    5. Let lprim be ? ToPrimitive(lval).
    6. Let rprim be ? ToPrimitive(rval).
    7. If Type(lprim) is String or Type(rprim) is String, then
      7.a Let lstr be ? ToString(lprim).
      7.b Let rstr be ? ToString(rprim).
      7.c Return the String that is the result of concatenating lstr and rstr.
    8. Let lnum be ? ToNumber(lprim).
    9. Let rnum be ? ToNumber(rprim).
    10. Return the result of applying the addition operation to lnum and rnum.

    12.8.3 The Addition Operator ( + )

    7.1.1 ToPrimitive ( input [ , PreferredType ] )
    7.1.12ToString ( argument )
    7.1.3 ToNumber ( argument )

    5. Numbers

    999999999999999  // -> 999999999999999
    9999999999999999 // -> 10000000000000000
    
    10000000000000000       // -> 10000000000000000
    10000000000000000 + 1   // -> 10000000000000000
    10000000000000000 + 1.1 // -> 10000000000000002
    
    0.1 + 0.2 // -> 0.30000000000000004
    

    6.1.6 The Number Type
    0.30000000000000004.com

    6. HTML comments

    // valid comment
    <!-- valid comment too
    

    B.1.3 HTML-like Comments

    7. Array

    [] == ''   // -> true
    [] == 0    // -> true
    [''] == '' // -> true
    [0] == 0   // -> true
    [0] == ''  // -> false
    [''] == 0  // -> true
    
    [null] == ''      // true
    [null] == 0       // true
    [undefined] == '' // true
    [undefined] == 0  // true
    
    [[]] == 0  // true
    [[]] == '' // true
    
    [[[[[[]]]]]] == '' // true
    [[[[[[]]]]]] == 0  // true
    
    [[[[[[ null ]]]]]] == 0  // true
    [[[[[[ null ]]]]]] == '' // true
    
    [[[[[[ undefined ]]]]]] == 0  // true
    [[[[[[ undefined ]]]]]] == '' // true
    

    Abstract Equality Comparison

    1. If Type(x) is the same as Type(y), then
      1.a Return the result of performing Strict Equality Comparison x === y.
    2. If x is null and y is undefined, return true.
    3. If x is undefined and y is null, return true.
    4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
    5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
    6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
    7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
    8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
    9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
    10. Return false.

    7.2.13 Abstract Equality Comparison

    8. Trailing commas in array

    let a = [,,,]
    a.length     // -> 3
    a.toString() // -> ',,'
    

    MDN - Trailing commas

    9. [] is equal ![]

    [] == ![] // -> true
    

    7.2.13 Abstract Equality Comparison
    12.5.9 Logical NOT Operator ( ! )

    参考

    Github - wtfjs

    相关文章

      网友评论

        本文标题:[JavaScript] WTFJS

        本文链接:https://www.haomeiwen.com/subject/qzlqrxtx.html