《你不知道的Javascript--中卷 学习总结》(语法)

语句和表达式

1、ES7规范有一项"do表达式"提案,类似下面这样。do{}表达式执行一个代码块(包含一个或多个语句),并且返回其中最后一个语句的返回值,然后赋值给变量a。

    var a,b;
    a = do{
        if(true){
            b = 4 + 32;
        }
    }
    
    a // 42
复制代码

2、可以使用,语句系列逗号运算符将多个独立的表达式语句串联成一个语句。(a++,a中第二个表达式a在a++之后执行,结果为43,并被赋值给b)

    var a = 42,b;
    b = (a++,a)
    
    a // 43
    b // 43
复制代码

3、delete运算符可以删除对象中的属性和数组中的单元。(如果操作成功,delete返回true,否则返回false)

    var obj = {
        a:42
    }
    obj.a // 42
    delete obj.a // true
    obj.a //undefined
复制代码

4、使用var a = b = 42,不会对变量进行声明,在严格模式中这样会产生错误,或者会无意中创建一个全局变量(b)。

5、代码块

   [] + {}  // "[object Object]"

   {} + []  // 0
复制代码

第一行代码中,[]被强制类型转换为"",而{}会被强制类型转换为"[object Object]"

第二行代码中,{}被当做一个独立的空代码块,代码块结尾不需要分号,最后+[]将[]显示强制类型转换为0。

6、事实上Javascript没有else if,但if和else只包含单条语句的时候可以省略代码块的{}

运算符优先级

1、运算符的优先级比=低,用,来连接一系列语句的时候,它的优先级最低,其他操作数的优先级都比它高。

    var a = 42,b;
    b = (a++,a)
    
    a // 43
    b // 43
    
    
    var a = 42,b;
    b = a++,a;
    a // 43
    b // 42
复制代码

2、&&运算符的优先级高于=。如果不加括号的话,就会执行作(str && matches)= str.match。这样会出错,由于(str && matches)的结果是一个undefined,因此它不能出现在=运算符的左边。

    if(str && (matches = str.match(/[aeiou]/g))){
        
    }
复制代码

3、&&运算符先于||执行,而且执行顺序并非我们所设想的从左到右。

    false && true || true  // true
    (false && true) || true // true
    
    
    true || false && false  // true
    (true || false) && false // false
    true || (false && false) // true
复制代码

4、&&运算符的优先级高于||,而||的优先级又高于?:

    a && b || c ? c || b ? a : c && b : a
    等于
    (a && b || c) ? (c || b) ? a : (c && b) : a
复制代码

5、?:是右关联的。

    a ? b : c ? d : e
    等于
    a ? b : (c ? d : e)
复制代码

6、暂时性死区

    {
        a = 2; // ReferenceError  变量a初始化之前赋值会抛出错误
        let a;
    }
    
    // 对未声明的变量使用typeof不会产生错误
    {
        typeof a;  // undefined
        typeof b; // ReferenceError
        let b;
    }
复制代码

函数参数

1、在ES6中,如果参数被省略或者值为undefined,则取该参数的默认值。

    function foo(a = 42,b = a+1){
        console.log(a,b)
    }
    foo() // 42 43
    foo(undefined) // 42 43
    foo(5) // 5 6
    foo(void 0,7) // 42 7
    foo(null) // null 1
复制代码

2、如果向函数传递undefined,则arguments数组中会出现一个值为undefined的单元,而不是默认值。

    function foo(a = 42,b = a + 1) {
        console.log(
            arguments.length,a,b,
            arguments[0],arguments[1]
        )
    }
    
    foo() // 0 42 43 undefined undefined
    foo(10) // 1 10 11 10 undefined
    foo(10,undefined) // 2 10 11 10 undefined
    foo(10,null) // 2 10 null 10 null
复制代码

3、向函数传递参数时,arguments数组中的对应单元会和命名参数建立关联以得到相同的值,不传递不建立关联(严格模式没有建立关联)

    function foo(a){
        a = 42;
        console.log(arguments[0])
    }
    foo(2) // 42 (linked)
    foo()  // undefined(not linked)
    
    
    function foo(a){
        "use strict"
        a = 42;
        console.log(arguments[0])
    }
    foo(2) // 2 (not linked)
    foo()  // undefined(not linked)
复制代码

try...finally

1、finally中的代码总是会在try之后执行,如果有catch的话则在catch之后执行,也可以将finally中的代码看作是一个回调函数,最后一定被调用。

    function foo() {
        try{
            return 42
        }
        finally {
            console.log('Hello')
        }
        
        console.log('never runs')
    }
    
    console.log(foo())
    // Hello
    // 42
    
    function foo() {
        try{
            throw 42
        }
        finally {
            console.log('Hello')
        }
        
        console.log('never runs')
    }
    
    console.log(foo())
    // Hello
    // Uncaught Exception:42
    
    
    function foo() {
        try{
            return 42
        }
        finally {
            throw "Oops"
        }
        
        console.log('never runs')
    }
    
    console.log(foo())
    // Uncaught Exception:Oops
复制代码

2、finally中的return会覆盖try和catch中的return的返回值。

    function foo(){
        try{
            return 42;
        }
        finally{
            // 没有返回语句,所以没有覆盖
        }
    }
    
    function bar() {
        try{
            return 42;
        }
        finally{
            return;
        }
    }
    
    function baz() {
        try{
            return 42;
        }
        finally{
            return "Hello";
        }
    }
    
    foo() // 42
    bar() // undefined
    baz() // Hello
复制代码

switch

1、a和case表达式的匹配算法与===相同。

    var a = '42'
    switch(true){
        case a == 10 :
            break;
        case a == 42:
            break;
        default:    
    }
复制代码

2、尽管可以使用==,但switch中true和true之间仍然是严格相等比较。即如果case表达式的结果为真值,但不是严格意义上的true,则条件不成立。

    var a = 'hello world'
    var b = 10;
    switch(true){
        case (a || b == 10): // 结果为'hello world' 不会执行这里
            break; // 永远执行不到这里
        default:
            
    }
复制代码

转载于:https://juejin.im/post/5d08fc1051882572d746fb03

猜你喜欢

转载自blog.csdn.net/weixin_34194551/article/details/93163955