2020-04-23

Javascript-E...

Javascript – Expressions

Atom

Expressions 表达式

Grammar

引导:Grammar Tree vs Priority

  • + -
  • * /
  • ()

Left Handside & Right Handside

Left Handside

  • Left Handside
  • 极限是 call

Member

  • a.b

  • a[b]

  • foo`string`

    1
    2
    3
    4
    5
    var name = "Elle"
    function foo() {
    console.log(arguments)
    }
    foo`Hello ${name}!`
  • super.b

    • 只能在 constructor 里使用
  • super[‘b’]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Parent {
    constructor() {
    this.a = 1
    }
    }
    class Child extends Parent {
    constructor() {
    super()
    console.log(this.a)
    }
    }
    Parent.a = 2;
    new Child
    • super 截图
  • new.target

    • 函数外面不能使用,只能在函数里使用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function foo() {
      console.log(this)
      }
      // 存在一个伪造对象的可能,无法知道对象是否是被 new 调起
      var fakeObj = {}
      Object.setPrototypeOf(fakeObj, foo.prototype)
      fakeObj.constructor = foo
      foo.apply(fakeObj)
      fakeObj instanceof foo
      1
      2
      3
      4
      5
      6
      7
      function foo() {
      console.log(new.target)
      }

      foo()

      new foo()
  • new Foo()

    • high priority

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function cls1(s) {
      console.log(s)
      }
      function cls2(s) {
      console.log("2", s)
      return cls1
      }

      new new cls2("goog")
    • new Foo()

  • Member Expressions 返回的是一个 Reference 类型

    • Reference

      1
      2
      3
      4
      5
      var o = { x: 1 }
      o.x + 2
      1 + 2
      delete o.x
      delete 1

New

  • new Foo

  • new Foo() 优先级高

  • Example

    • new a()()

    • new new a()

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      function cls1(s) {
      console.log(s)
      }
      function cls2(s) {
      console.log("2", s)
      return cls1
      }
      console.log('-=-=-=-new cls2-=-=-=-=')
      new cls2
      console.log('-=-=-=-cls2("good")-=-=-=-=')
      cls2("good")
      console.log('-=-=-=-new cls2("good")-=-=-=-=')
      new cls2("good") // 返回回来 cls2 实例,cls1对象
      console.log('-=-=-=-new (cls2("good"))-=-=-=-=')
      new (cls2("good"))
      console.log('-=-=-=-new (new cls2)-=-=-=-=')
      new (new cls2)
      console.log('-=-=-=-new new cls2("good")-=-=-=-=')
      new new cls2("good")
    • new Foo  优先级

Call

  • foo()
  • super()
  • foo()[‘b’]
  • foo().b
  • foo()`abc`

Right Handside

Update

  • UpdateExpression

    • no LineTerminator here

    • no LineTerminator here

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      var a = 1, b = 1, c = 1;
      a
      ++
      b
      ++
      c
      console.log([a, b, c])
      a/*

      */++
      b/*

      */++
      c
      console.log([a, b, c])
  • a ++

  • a –

  • – a

  • ++ a

Unary 单目运算符

  • delete a.b

  • void foo()

    • void 不是返回值,是运算符在 JS 中

    • 不管后面是什么,都返回 undefined

    • IIFE 立即执行函数

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      for (var i = 0; i < 10; i ++) {
      var button = document.createElement('button');
      documents.body.append(button);
      button.innerHTML = 1;
      button.onClick = function () {
      console.log(i)
      }
      }
      // 点那个按钮,都是10,为解决这个问题,我们可以使用IIFE
      for (var i = 0; i < 10; i ++) {
      var button = document.createElement('button');
      documents.body.append(button);
      button.innerHTML = 1;
      (function(i) {
      button.onClick = function (i) {
      console.log(i)
      }
      })()
      }
      // 如果前面不加分号,在一些写法中,会发生粘起来错误
      (function(i) {
      button.onClick = function (i) {
      console.log(i)
      }
      })()

      (function(i) {
      button.onClick = function (i) {
      console.log(i)
      }
      })()
      // 最稳妥的就是,在前面加上void
      for (var i = 0; i < 10; i ++) {
      var button = document.createElement('button');
      documents.body.append(button);
      button.innerHTML = 1;
      void function(i) {
      button.onClick = function (i) {
      console.log(i)
      }
      }()
      }
      // 并且语义正确,我们并不需要IIFE的返回值
  • typeof a

    1
    2
    typeof null
    typeof function() {}
    • typeof
  • + a

  • - a

  • ~ a 按位取反

  • ! a 取非

    • !!1
  • await a

Exponental

  • **
    • 3 ** 2 ** 3
    • 3 ** (2 ** 3)
    • Exponental

Multiplicative

  • * / %
    • JS 中有1种乘法运算符
      • 运行时
        • number
        • string

Additive

  • + -
    • JS 中有2种加法运算符
      • 运行时
        • number
        • string

Shift 左右移位

  • << >> >>>

Relationship 比较

  • < > <= >= instanceof in

Equality

  • ==
  • !=
  • ===
  • !==

Bitwise

  • & ^ |

Logical

  • 没有任何 boolean 转换

  • &&

    • 有短路逻辑

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      function foo1() {
      console.log(1)
      return false
      }
      function foo2() {
      console.log(2)
      }
      foo1() && foo2()

      foo1() || foo2()
    • && 短路逻辑运行截图

  • ||

Conditional

  • ? :

    • 同样有短路逻辑

      1
      false ? foo1() : foo2()
    • 三目运算符短路逻辑

,

Runtime

Type Convertion

  • Type Convertion
  • undefined –> number NAN

Boxing & Unboxing

1
2
3
4
5
6
7
8
9
10
11
12
// Number String Boolean Symbol
new Number(1)
new String('hello')
new String('hello').length
"hello".length
typeof "hello"
typeof new String('hello')
!new String('')
!""
// Number String Boolean 不作为 new 调用,就是转换成普通类型
String(1)
new String(1)
  • Boxing & Unboxing

  • toPremitive()

  • toString vs valueOf

    • toString vs valueOf

      1
      2
      3
      4
      5
      6
      7
      1 + {}
      1 + {valueOf(){return 2}}
      1 + {toString(){return 2}}
      1 + {toString(){return 4}}
      1 + {toString(){return "4"}}
      1 + {valueOf(){return 1}, toString(){return "2"}}
      "1" + {valueOf(){return 1}, toString(){return "2"}}
      • toString vs valueOf

Reference

Object

Key

支持写

  • delete
  • assign

Statement

Structure

Program/Module

ps. checkSign

1
2
3
4
5
6
7
8
9
function check(number) {
if (1 / number === Infinity) {
return 1
}
if (1 / number === -Infinity) {
return -1
}
return number / Math.abs(number)
}
  • 【未完】Infinity 判断

  • 【未完】直接用流取出符号位