表达式与运算符

运算符

赋值运算符

一个赋值运算符将它右边操作数的值赋值给它左边的操作数。JavaScript包含的赋值表达式如下:

名称 简写的操作符 含义
赋值操作符 x = y x = y
加法赋值操作符 x += y x = x + y
减法赋值操作符 x -= y x = x - y
乘法赋值操作符 x *= y x = x * y
除法赋值操作符 x /= y x = x / y
求余赋值操作符 x %= y x = x % y
求幂赋值操作符 x **= y x = x ** y
左移位赋值操作符 x <<= y x = x << y
右移位赋值操作符 x >>= y x = x >> y
无符号右移位赋值操作符 x >>>= y x = x >>> y
按位与赋值操作符 x &= y x = x & y
按位异或赋值操作符 x ^= y x = x ^ y
按位或赋值操作符 x |= y x = x | y
解构运算符

对于更复杂的赋值,解构赋值语法可以将属性或值从对象或数组中取出,赋值给其他变量。例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20


// Stage 4(已完成)提案中的特性
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
  • 解构数组

    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
    44
    45
    46
    47
    48
    49
    50
    // 变量声明并赋值时的解构
    let foo = ['one', 'two', 'three'];
    let [one, two, three] = foo;
    console.log(one, two, three); // 'one', 'two', 'three'

    // 变量先声明后赋值时的解构
    let a, b;
    [a, b] = [1, 2];
    console.log(a, b); // 1, 2

    // 默认值
    let [a=3, b=5] = [1];
    console.log(a, b); // 1, 5

    // 交换变量
    let a = 1;
    let b = 3;
    [a, b] = [b, a];
    console.log(a, b); // 3, 1

    // 解析一个从函数返回的数组
    function f() {
    return [1, 3, 5];
    }
    let [a, b, c] = f();
    console.log(a, b, c); // 1, 3, 5

    // 忽略某些返回值
    function f() {
    return [1, 3, 5];
    }
    let [a, b] = f();
    console.log(a, b); // 1, 3
    [,,] = f(); // 忽略全部返回值

    // 将剩余数组赋值给一个变量
    let [a, ...b] = [1, 2, 3];
    console.log(a, b); // 1, [2, 3]

    // 用正则表达式匹配提取值
    function parseProtocol(url) {
    let parsedUrl = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
    if(!parsedUrl) {
    return false;
    }
    console.log(parsedUrl);
    let [, protocol, fullhost, fullpath] = parsedUrl;
    return protocol;
    }
    console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript'));
  • 结构对象

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    let o = {p: 42, q: true};
    console.log(p, q); // 42, true

    // 无声明赋值
    let a, b;
    ({a, b} = {a: 1, b: 2}); // 括号()在使用对象字面量无声明结构赋值时是必须的
    // {a, b} = {a: 1, b: 2} 左边会被认为是一个代码块而不是对象字面量
    console.log(a, b); // 1, 2

    // 给新的变量名赋值
    let o = {p: 42, q: true};
    let {p: foo, q: bar} = o;
    console.log(foo, bar); // 42, true

    // 默认值
    let {a=10, b=5} = {a: 1};
    cosole.log(a, b); // 1, 5

    // 给新的变量命名并提供默认值
    let {a:aa=5, b:bb=10} = {a: 1};
    console.log(aa, bb); // 1, 10

    // 函数参数默认值
    // ES5版
    function drawES5Chart(options) {
    options = options === undefined ? {} : options;
    let size = options.size === undefined ? 'big' : options.size;
    let cords = options.cords === undefined ? {x: 0, y: 0} : options.cords;
    let radius = options.size === undefined ? 25 : options.radius;
    console.log(size, cords, radius);
    }
    drawES5Chart({
    cords: {x: 18, y: 30},
    radius: 30
    })
    // ES6版
    function drawES6Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
    console.log(size, cords, radius);
    }
    drawES6Chart({
    cords: {x: 18, y: 30},
    radius: 30
    })

    // 解构嵌套对象和数组
    const metadata = {
    title: 'test',
    translations: [
    {
    title: 'JavaScript'
    }
    ]
    }
    let {
    title: englishTitle,
    translations: {
    title: localeTitle
    }
    } = metadata;
    console.log(englishTitle, localeTitle); // test, JavaScript

    // for...of迭代和解构
    let people = [
    {
    name: 'Mike',
    age: 18,
    family: {
    mother: 'Jane',
    father: 'Harry',
    brother: 'Samantha'
    }
    },
    {
    name: 'Tom',
    age: 20,
    family: {
    mother: 'Norah',
    father: 'Richard',
    brother: 'Howard'
    }
    }
    ];
    for(let {name: n, family: {father: f}, age: a} of people) {
    console.log(`name: ${n}, age: ${a}, father: ${f}`);
    }
    // name: Mike, age: 18, father: Harry
    // name: Tom, age: 20, father: Richard

    // 从作为函数实参的对象中提取数据
    function userId({id}) {
    return id;
    }
    function whois({displayName: displayName, fullName: { firstName: name }}) {
    console.log(`${displayName} is ${name}`);
    }
    let user = {
    id: 42,
    displayName: 'jdoe',
    fullname: {
    firstName: 'John',
    lastName: 'Doe'
    }
    }
    cosole.log(`userId: ${userId(user)}`) // userId: 42
    whois(user); // jdoe is John

    // 对象属性计算名和解构
    let key = 'z';
    let {[key]: foo} = {z: 'bar'};
    cosnole.log(foo); // bar

    // 对象解构中的Rest
    let {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
    console.log(a, b, rest); // a, 2, {c: 3, d: 4}

    // 无效的JavaScript标识符作为属性名称
    const foo = {'fizz-buzz': true};
    const {'fizz-buzz': fizzBuzz} = foo;
    console.log(fizzBuzz); // true

    // 解构对象时查找原型链
    let obj = {self: '123'};
    obj.__proto__.port = '456';
    const {self, port} = obj;
    console.log(self, port); // 123, 456

比较运算符

比较运算符比较它的操作数并返回一个基于表达式是否为真的逻辑值,操作数可以是数字、字符串、逻辑、对象值。字符串比较是基于标准的字典顺序,使用Unicode值。在多数情况下,如果两个操作数不是相同类型,JavaScript会尝试转换它们为恰当的类型来比较。类型转换的例外使用===!==操作符,它们不会在检查相等之前转换操作数的类型。

运算符 描述 实例
等于== 当两边操作数相等时返回true 1 == '1'
不等于!= 当两边操作数不相等时返回true 1 != 2
严格等于=== 两边操作数相等且类型相同时返回true 1 === 1
严格不等于!== 当两边操作数不相等或类型不相同时返回true 1 !== '1'
大于> 当左边的操作数大于右边的操作数是返回true 2 > 1
小于< 当左边的操作数小于右边的操作数是返回true 1 < 2
大于等于>= 当左边的操作数大于或等于右边的操作数是返回true 2 >= 2
小于等于<= 当左边的操作数小于或等于右边的操作数是返回true 2 <= 2

算数运算符

算数运算符使用数值作为操作数并返回一个数值。注:除0会返回Infinity,除-0会返回-Infinity。除了标准的算数运算符(+-*/),JavaScript还提供了一下算数运算符:

操作符 描述 实例
求余% 二元运算符,返回相除之后的余数 12 % 5 // 2
自增++ 一元运算符,将操作数的值加1。如果放在操作数的前面则返回加1后的值,如果放在操作数后面则返回操作数原值,再将操作数加1。 let x = 3
x++ //3
++x // 4
自减-- 一元运算符,将操作数的值减1。前后规则和则增相同 let x = 3
x-- //3
--x // 2
一元负值符- 一元运算符,返回操作数的负值 -x
一元正操作符+ 一元运算符,返回操作数的正值 +x
指数运算符** 计算底数的指数次方 x**y //x的y次方

位运算符

位运算符将它的操作数当做32位元的二进制串。位运算符在二进制上执行运算,返回标准的JavaScript数值。

运算符 用法 描述
按位与& a & b 在a和b的位表示中,每一个对应的位都是1则返回1,否则返回0
按位或| a | b 在a和b的位表示中,每一个对应的位只要有1个是1则返回1,否则返回0
按位异或^ a ^ b 在a和b的位表示中,每一个对应的位两个不相同则返回1,否则返回0
按位非~ ~ a 翻转操作数的位
左移<< a << b 将a的二进制串想左移动b位,右边加入0
算数右移>> a >> b 将a的二进制串向右移动b位,丢弃被移除的所有位
无符号右移>>> a >>> b 将a的二进制串向右移动b位,丢弃被移除的所有位,将左边空出的位都补0

逻辑运算符

逻辑运算符常用于布尔值之间

运算符 范例 描述
逻辑与&& a && b 如果a能被转成false,则返回a,否则返回b。当&&用于布尔值时,当操作数都为true时返回true,否则返回false
逻辑或|| a || b 如果a能被转成true,则返回a,否则返回b。当||用于布尔值时,当操作数有一个为true时返回true,否则返回false
逻辑非! !a 如果操作数能转换true则返回false,否则返回true

一元操作符

  • delete

    delete删除一个对象或一个对象的属性或者一个数组中的键值

    1
    2
    3
    4
    5
    6
    7
    let o = {a: 1, b: 2};
    delete o.b;
    console.log(o); // {a: 1}

    let arrs = [1, 2, 3, 4, 5];
    delete arrs[0];
    console.log(arrs); // [empty , 2, 3, 4, 5]
  • typeof

    typeof返回一个表示操作数类型的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    console.log(typeof 'string');    // string
    console.log(typeof 1); // number
    console.log(typeof {}); // object
    console.log(typeof []); // object
    console.log(typeof (function() {})); // function
    console.log(typeof null); // object
    console.log(typeof undefined); // undefined
    console.log(typeof true); // boolean
  • void

    void表明一个运算没有返回值。

    1
    <a href="javascript: void(0)">test</a>

关系操作符

  • in

    in操作符如果所制定得属性确实存在于所制定的对象中,则返回true。

    1
    2
    3
    4
    5
    6
    7
    let arrs = ['a', 'b', 'c'];
    console.log(0 in arrs); // true
    console.log(1 in arrs); // true
    console.log('a' in arrs); // false
    let o = {a: 1, b: 2};
    console.log(a in o); // true
    console.log(1 in o); // false
  • instanceof

    instanceof操作符如果所判断的对象是所指定的对象类型,则返回true。

    1
    2
    var theDay = new Date(1995, 12, 17);
    console.log(theDay instanceof Date);

表达式

基本表达式

  • this

    this关键字被用于指代方法中正在被调用的对象,

左值表达式

  • new

    new可以创建一个自定义类型或者是预置类型的对象实例。

  • super

    super可以用来调用一个对象父类的函数

  • 扩展语句

    扩展语句允许一个表达式在原地展开。

    1
    2
    3
    let arr1 = [1, 2, 3];
    let arr2 = [...arr1, 4, 5, 6];
    console.log(arr2); // [1, 2, 3, 4, 5, 6]

本文参考资料

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • © 2019-2021 musi

请我喝杯咖啡吧~

支付宝
微信