可选链与非空操作符

? : 可选链操作符,用于访问对象属性时,如果该属性不存在,则返回 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>
相关推荐
爱写bug的野原新之助1 分钟前
爬虫之补环境:加载原型链
前端·javascript·爬虫
陈广亮9 分钟前
工具指南7-Unix时间戳转换工具
前端
NGBQ1213816 分钟前
Adobe-Premiere-Pro-2026-26.0.2.2-m0nkrus 全解析:专业视频编辑软件深度指南
前端·adobe·音视频
北城笑笑17 分钟前
Chrome:Paused in debugger 的踩坑实录:问题排查全过程与终极解决方案( 在调试器中暂停 )
前端·chrome
haorooms19 分钟前
Promise.try () 完全指南
前端·javascript
kyriewen20 分钟前
闭包:那个“赖着不走”的家伙,到底有什么用?
前端·javascript·ecmascript 6
斌味代码23 分钟前
el-popover跳转页面不隐藏,el-popover销毁
前端·javascript·vue.js
该怎么办呢24 分钟前
cesium核心代码学习-01项目目录及其基本作用
前端·3d·源码·webgl·cesium·webgis
踩着两条虫31 分钟前
AI 驱动的 Vue3 应用开发平台 深入探究(十九):CLI与工具链之Create VTJ CLI 参考
前端·ai编程·vite
天下无贼!42 分钟前
【Python】2026版——FastAPI 框架快速搭建后端服务
开发语言·前端·后端·python·aigc·fastapi