可选链与非空操作符

? : 可选链操作符,用于访问对象属性时,如果该属性不存在,则返回 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>
相关推荐
掘金安东尼7 小时前
纯 CSS 实现弹性文字效果
前端·css
牛奶7 小时前
Vue 基础理论 & API 使用
前端·vue.js·面试
牛奶7 小时前
Vue 底层原理 & 新特性
前端·vue.js·面试
anOnion8 小时前
构建无障碍组件之Radio group pattern
前端·html·交互设计
pe7er8 小时前
状态提升:前端开发中的状态管理的设计思想
前端·vue.js·react.js
SoaringHeart9 小时前
Flutter调试组件:打印任意组件尺寸位置信息 NRenderBox
前端·flutter
晚风予星9 小时前
Ant Design Token Lens 迎来了全面升级!支持在 .tsx 或 .ts 文件中直接使用 Design Token
前端·react.js·visual studio code
sunny_10 小时前
⚡️ vite-plugin-oxc:从 Babel 到 Oxc,我为 Vite 写了一个高性能编译插件
前端·webpack·架构
GIS之路10 小时前
ArcPy 开发环境搭建
前端
林小帅11 小时前
【笔记】OpenClaw 架构浅析
前端·agent