JavaScript中常用的哪些有趣的表达式和运算符

本文介绍了JavaScript中的立即调用函数表达式(IIFE)在Vue3中的应用,以及逻辑运算符如&&、&&=、||、||=在条件判断和赋值中的用法。同时,文章探讨了空值合并运算符(??)和??=的安全赋值功能,以及可选链(?.)在处理可能存在或不存在的对象属性时的便利性。最后,展示了展开语法(...)在数组和对象操作中的作用。
摘要由CSDN通过智能技术生成

壹、IIFE 立即调用函数表达式 🕦 🕦 🕦 🕦

IIFE(立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数。这个本不应该出现在这里,懒得拿出来单独重新写,就放这里吧。下面是在vue3中的一个demo。

demo中可以发现它在vue3中的优先级高于onBeforeMount,所以你可以用它做一些特殊的业务处理🎃🎃🎃🎃

<script lang="ts">
export default defineComponent({
  setup() {

    (function(){
      console.log('立即调用函数表达式11111')
    })()

    onBeforeMount(() => {
      console.log('组件挂载到节点上之前执行的函数')
    });

    !function() {
      console.log('立即调用函数表达式22222')
      return ''
    }();

    onMounted(() => {
      console.log('组件挂载完成后执行的函数;')
    });

    (function(){
      console.log('立即调用函数表达式33333')
    }());
  }
})
</script>

贰、&&、&&= 🕐 🕐 🕐 🕐

&&当且仅当其所有操作数都为真时

&&= 逻辑 AND 赋值 ( x &&= y) 运算符仅在x为真时才赋值。

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      info1: {
        name: 'Etc.End',
        age: 28,
        gender: '男',
        weChat: 'SH--TS',
        state: 1,
        enable: true,
      },
      info2: {
        name: 'Annie',
        age: 28,
        gender: '',
        weChat: 'SH--TS',
        state: 0,
        enable: false,
      }
    })

    // 记住在js中0为false, 其他都为true

    if (data.info1.state && data.info2.state) {
      console.log('不会通过校验!!!')
    }

    // 这里是因为info2中的状态为0
    // !data.info2.state是取反
    // 即data.info2.state为false 所以!data.info2.state 就为 true
    if (data.info1.state && !data.info2.state) {
      console.log('通过校验!!!')
    }

    // 正常的写法
    if (data.info1.enable) {
      data.info1.age = 18
      console.log(JSON.stringify(data.info1))
      // {"name":"Etc.End","age":18,"gender":"男","weChat":"SH--TS","state":1,"enable":true}
    }

    // 使用运算符&&进行短路运算
    // 仅在&&左侧为真时,才会执行右侧的代码逻辑
    data.info1.enable && (data.info1.age = 20)
    console.log(JSON.stringify(data.info1))
    // {"name":"Etc.End","age":20,"gender":"男","weChat":"SH--TS","state":1,"enable":true}

    // 正常的写法
    if (data.info1.gender) {
      data.info1.gender = '男性'
      console.log(JSON.stringify(data.info1))
      // {"name":"Etc.End","age":20,"gender":"男性","weChat":"SH--TS","state":1,"enable":true}
    }

    // 使用运算符&&=再进行简化
    data.info1.gender &&= '男性同胞'
    console.log(JSON.stringify(data.info1))
    // {"name":"Etc.End","age":20,"gender":"男性同胞","weChat":"SH--TS","state":1,"enable":true}
  }
})
</script>

叁、||、||=  🕜  🕜  🕜  🕜

|| 当且仅当其一个或多个操作数为真时,一组操作数的逻辑 OR ( ||) 运算符(逻辑析取)为真。

||= 逻辑或赋值(x ||= y)运算仅在 x 为虚值时赋值。

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      info1: {
        name: 'Etc.End',
        age: 28,
        gender: '男',
        weChat: 'SH--TS',
        state: 1,
        enable: true,
      },
      info2: {
        name: 'Annie',
        age: 28,
        gender: '',
        weChat: 'SH--TS',
        state: 0,
        enable: false,
      }
    })

    // 记住在js中0为false, 其他都为true

    // 正常的写法
    if (!data.info2.state) {
      data.info2.gender = '男'
      console.log(JSON.stringify(data.info2))
      // {"name":"Annie","age":28,"gender":"男","weChat":"SH--TS","state":0,"enable":false}
    }

    // 使用运算符||进行短路运算
    // 仅在||左侧为假时,才会执行右侧的代码逻辑
    data.info2.state || (data.info2.gender = '男性')
    console.log(JSON.stringify(data.info2))
    // {"name":"Annie","age":28,"gender":"男性","weChat":"SH--TS","state":0,"enable":false}

    // 正常的写法
    if (!data.info2.state) {
      data.info2.state = data.info1.state
      console.log(JSON.stringify(data.info1))
      // {"name":"Etc.End","age":28,"gender":"男","weChat":"SH--TS","state":1,"enable":true}
    }

    // 使用运算符||=再进行简化
    data.info1.gender = '男性一枚'
    data.info2.gender = ''
    data.info2.gender ||= data.info1.gender
    console.log(JSON.stringify(data.info2))
    // {"name":"Annie","age":28,"gender":"男性一枚","weChat":"SH--TS","state":1,"enable":false}
  }
})
</script>

肆、??、??=  🕙  🕙  🕙  🕙

空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

与逻辑或运算符(||)不同,逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。

 逻辑空赋值运算符(x ??= y)仅在 x 是空值(null 或 undefined)时对其赋值。

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      count: 22,
      count1: null,
    })

    // 记住在js中0为false, 其他都为true

    data.count = data.count ?? 10
    data.count1 = data.count1 ?? 10
    console.log(data.count)
    // 22
    console.log(data.count1)
    // 10

    // 恢复默认值
    data.count = 22
    data.count1 = null

    data.count ??= 10
    data.count1 ??= 10
    console.log(data.count)
    // 22
    console.log(data.count1)
    // 10

  }
})
</script>

伍、?.  🕥 🕥 🕥 🕥

可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。 当尝试访问可能不存在的对象属性时,可选链运算符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链运算符也是很有帮助的。

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      info: {
        name: 'Etc.End',
        age: 28,
        gender: '男',
        weChat: 'SH--TS',
        state: 1,
        enable: true,
        more: {
          address: '云南省昆明市'
        },
        list: [1, 2, 3, 4, 5, 6, 7]
      }
    })

    // 虽然info不包含interest这个对象,但这里不会报错,因为使用?.会进行短路求值
    if (data.info?.interest?.football == 100) {
      console.log(123)
    }

    // 这里就会报错,因为使用.不会进行短路操作。
    // if (data.info.interest.football == 100) {
    //   console.log(123)
    // }

    console.log(data.info?.more?.['address']) // 云南省昆明市
    // ?. 除了用于object,还可以用于array和function
    console.log(data.info?.list?.[1]) // 2
    console.log(data.info?.list?.[7]) // undefined

    // 结合??的使用
    const name = data.info?.name ?? 'tiger'
    console.log(name) // Etc.End
  }
})
</script>

陆、~~ 🕚 🕚 🕚 🕚

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      value: 0.123456,
      value1: 3.1415926,
      value2: -10.258,
      value3: 4.4,
      value4: 4.5,
      value5: 4.6,
      value6: -4.4,
      value7: -4.5,
      value8: -4.6,
      value9: true,
      value10: false,
      value11: [],
      value12: '',
      value13: {},
    })

    console.log(~~data.value) // 0
    console.log(~~data.value1) // 3
    console.log(~~data.value2) // -10
    console.log(~~data.value3) // 4
    console.log(~~data.value4) // 4
    console.log(~~data.value5) // 4
    console.log(~~data.value6) // -4
    console.log(~~data.value7) // -4
    console.log(~~data.value8) // -4

    console.log(~~data.value9) // 1
    console.log(~~data.value10) // 0
    console.log(~~data.value11) // 0
    console.log(~~data.value12) // 0
    console.log(~~data.value13) // 0
  }
})
</script>

柒、... 🕚 🕚 🕚 🕚

展开语法 (Spread syntax), 可以在函数调用/数组构造时,将数组表达式或者 string 在语法层面展开;还可以在构造字面量对象时,将对象表达式按 key-value 的方式展开。(译者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)

<script lang="ts">
export default defineComponent({
  setup() {

    let data = reactive({
      value: 1,
      list: [1, 2, 3, 4],
      list1: [4, 5, 6, 7],
      obj: {
        name: 1,
        sex: 2
      },
      obj2: {
        iphone: '3'
      }
    })

    console.log(...data.list) // 1 2 3 4

    // 接收任意个参数
    const fun = (...x: any) => {
      console.log(x) // [1, 2, 3, 4]
    }

    fun(...data.list)

    console.log([...data.list, 'hello', ...'hello', 5])
    // [1, 2, 3, 4, 'hello', 'h', 'e', 'l', 'l', 'o', 5]

    // 克隆或者属性拷贝
    const newData = {...data}
    console.log(JSON.stringify(newData))
    // {"value":1,"value1":2,"value2":3,"list":[1,2,3,4]}
    // 下面的语句发现data发生了变化,但是newData不受影响
    data.value = 100
    console.log(JSON.stringify(data))
    // {"value":100,"value1":2,"value2":3,"list":[1,2,3,4]}

    // 合并两个数组,之前会用到concat
    console.log(data.list.concat(data.list1))
    // [1, 2, 3, 4, 4, 5, 6, 7]
    // 优雅一点,这里如果之前没有了解过展开语法的话,会看得很懵
    console.log([...data.list, ...data.list1])
    // [1, 2, 3, 4, 4, 5, 6, 7]

    // 合并除了针对数组,还可以作用到对象上面,一样的效果
    const obj1 = {...data.obj}
    console.log(obj1)
    // {name: 1, sex: 2}
    console.log({...data.obj, ...data.obj2})
    // {name: 1, sex: 2, iphone: '3'}
  }
})
</script>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Etc.End

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值