【从源码探秘到JS基础】逗号运算符

75 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

前言

只要阅读过JS项目的压缩源码的朋友都可以发现,在源码中,为了减少代码的行数,使用了特别多逗号运算符。

最近自己在学习TS的装饰器,在TS编译后成JS的压缩代码中也发现很多关于逗号运算符的使用例子,虽然平时我们在写代码的过程中不会去选择使用逗号运算符,但是了解和学习逗号运算符对于我们阅读压缩代码有很大的帮助!!!

先来看看这几个简单的题目,测测你对逗号运算符的掌握程度吧~~~

  • 题目①

    let a
    a = 10, 20
    console.log(a);    // 10
    
  • 题目②

    let a
    a = (10, 20)
    console.log(a);   // 20
    
  • 题目③

    let a = 10, 20;     // Uncaught SyntaxError: Unexpected number
    console.log(a);   
    
  • 题目④

    var name = "杜甫"
    var obj = {
        name: "李白",
        show() {
            console.log(this.name);
        }
    };
    (0, obj.show)()   // 杜甫
    

如果你全部答对了,那么恭喜你下面讲的对你来说是小儿科,如果不对,那就在下面的问题去寻找错题的原因吧!!

逗号表达式

一般逗号表达式形式为表达式1,表达式2,表达式3........

逗号表达式对它的每个表达式求值(从左到右),并返回最后一个表达式的值最为逗号表达式的值

1,2,3  // 3

优先级

题目1中,如果是10, 20逗号表达式先执行,那么a的值就应该是20,但是实际上a的值是10,所以不难看出赋值运算符的优先级都要高于逗号运算符

逗号运算符的优先级是所以运算符中最低的,所以只要在不改变表达式优先级的情况下,逗号运算符永远是最后执行

1 + 2, 2 + 3, 3 + 8   // 11

let a
a = 10, 20   // 先执行a = 10,可以理解为 (a = 10),20 表达式

题目2中通过括号改变了表达式的联合顺序,先执行10, 20逗号表达式得到值为20,再把20赋值给a

let a
a = (10, 20) // 先执行(10, 20)得到值20,然后再执行a = 20赋值表达式

连续赋值

可能你看到上面题目1的会感觉到很奇怪,为什么不把变量a的声明和赋值不能放在一起喃?

比如这样:

let a = 10, 20;  // 但是放入浏览器会发现报错 Uncaught SyntaxError: Unexpected number

你可能会猜想,如果在变量的声明赋值语句中,不能使用逗号运算符,但是却不是这样的

let a = (10, 20)  // 20

很明显是可以使用,这里其实有一个隐藏的规则:在声明赋值语句中使用逗号运算符,每个逗号运算符的操作数必须都是赋值语句或者变量字面量

let a, b;                  
// 合理,等同于 
let a;
let b;


let a = 20, c = 10 + 20;  
// 合理,等同于 
let a = 20;
let b = 10 + 20;


let a = 10, 20;           
// 不合理,等同于 
let a = 10;
let 20          //这里会报错

所以很容易理解题目3为什么是报错了吧~~~

一个小的面试题

题目4就是一个面试题

var name = "杜甫"
var obj = {
    name: "李白",
    show() {
        console.log(this.name);
    }
};
(0, obj.show)()   // 这里(0, obj.show)表达式执行,等到值为 obj.show,再执行函数

// (0, obj.show)() 相当于
let fun = (0, obj.show)
fun()

其实不难看出fun的执行没有指定this,所以this就是window了,结果就是window上的name值