可选链与非空操作符

? : 可选链操作符,用于访问对象属性时,如果该属性不存在,则返回 undefined或null,而不是抛出错误导致页面报错。

! : 非空断言操作符,告诉编译器某个表达式不会是 null或undefined,从而避免类型检查错误。

TypeScript 复制代码
<template>
  <div class="option-sel-and-have-view">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>?与!的使用</span>
        </div>
      </template>
      <div>
        <el-text class="intro">
        ? ------------ 可选链操作符,用于访问对象属性时,如果该属性不存在,则返回 undefined或null,而不是抛出错误导致页面报错。
        </el-text>
      </div>
      <div>
        <el-text class="intro">
        ! ------------ 非空断言操作符,告诉编译器某个表达式不会是 null或undefined,从而避免类型检查错误。
        </el-text>
      </div>
      <div class="btnbox">
        <el-button type="primary" @click="clickedOptionSelect">
          点击触发 ? --------- 可选链操作符示例  
        </el-button>
        <el-button type="success" @click="clickedNonNullAssertion">
          点击触发 ! --------- 非空断言操作符示例
        </el-button>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
const clickedOptionSelect = () => {
    interface User {
        name: string;
        address?: {
        street: string;
        city: string;
        };
    }
    
    const user: User = {
        name: "Alice",
    };
    

    /* 
        使用可选链操作符访问地址属性,在一个对象属性深度层级较多时非常有用,
        比如const width = user.address?.street?.width, 
        然后这样就可以了 if(width) { ... }
    */
    const street = user.address?.street;
    if (street) {
        alert(`街道名称: ${street}`);
    } else {
        alert("地址信息不可用");
    }

    // 如果不用可选链操作符,会是下面这样写,当属性深度层级为多级时不使用可选链操作符代码会嵌套多个if,不易阅读
    if(user.address && user.address.street) {
        alert(`街道名称: ${user.address.street}`);
    } else {
        alert("地址信息不可用");
    }
}

const clickedNonNullAssertion = () => {
    interface User {
        name: string;
        address: {
            street: string;
            city: string;
        };
    }

    const user: User = {
        name: "Alice",
        address: {
            street: "123 Main St",
            city: "New York"
        }
    };

    // 使用非空断言操作符访问地址属性
    // 告诉编译器 user.address 不会是 null 或 undefined,如果不这样写eslint会有错误的提示,或者报错
    // 当属性层级比较多时,这样用也是非常简洁
    const street = user.address!.street;
    alert(`街道名称: ${street}`);
}
</script>

<style lang="scss" scoped>
.option-sel-and-have-view {
  width: 100%;
  height: 100%;
  overflow: auto;
  box-sizing: border-box;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
}

.el-alert {
  margin-top: 20px;
}

.intro {
  margin-top: 20px;
  font-size: 14px;
  color: rgb(84, 144, 229);
}

.btnbox {
  margin-top: 20px;
  display: flex;
  gap: 10px;
}

</style>
相关推荐
Lvan的前端笔记24 分钟前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习1 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194052 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风3 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn4 小时前
框架性能优化
前端
回眸&啤酒鸭5 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013845 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员5 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子6 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端
IT_陈寒6 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端