返回

尤大亲自揭秘:Vue 3 源码为何抛弃 ?. 可选链式操作符?

前端

可选链式操作符:简介

在现代 JavaScript 中,可选链式操作符 (?.) 可用于安全地访问嵌套对象的属性或方法,即使其中某一部分不存在也不会报错。它的工作原理是,如果操作符左边的对象为 null 或 undefined,则整个表达式返回 undefined,否则继续执行后面的代码。

const user = {
  name: 'John Doe',
  address: {
    street: '123 Main Street'
  }
};

console.log(user.address.street); // '123 Main Street'
console.log(user.address.zipCode); // undefined

console.log(user?.address?.zipCode); // undefined

在第二个示例中,如果 address 或 zipCode 属性不存在,?. 操作符会阻止访问,从而避免了 JavaScript 中常见的 TypeError。

尤大解析:Vue 3 源码中的抉择

尤雨溪在访谈中解释说,Vue 3 源码中之所以不使用 ?. 可选链式操作符,是因为该框架采用了响应式系统。这意味着,当一个被追踪的对象发生变化时,Vue 会自动更新视图。如果使用 ?. 操作符,可能会导致视图更新不及时或不准确。

例如,假设我们有一个 Vue 组件,其模板中使用了 ?. 操作符:

<template>
  <div>{{ user.address.street }}</div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        address: {
          street: '123 Main Street'
        }
      }
    };
  }
};
</script>

如果 user.address.street 的值发生变化,Vue 不会检测到它,因为 ?. 操作符阻止了组件访问该属性。这会导致视图中显示的街道地址与实际值不符。

替代解决方案:v-if 和 v-else

为了解决这个问题,Vue 3 采用了不同的方法:使用 v-if 和 v-else 指令。这些指令允许开发者有条件地渲染模板元素,具体取决于表达式的真假值。

<template>
  <div v-if="user.address">
    {{ user.address.street }}
  </div>
  <div v-else>
    No address provided
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        address: {
          street: '123 Main Street'
        }
      }
    };
  }
};
</script>

使用这种方法,Vue 会监视 user.address 对象的更改,并在值发生变化时自动更新视图。

性能考虑

尤雨溪还提到了性能方面的考虑。?. 操作符需要在运行时进行类型检查,这可能会增加应用程序的执行时间。而 v-if 和 v-else 指令不需要进行类型检查,因此效率更高。

总结

虽然可选链式操作符 (?.) 是一种有用的 JavaScript 特性,但它不适合 Vue 3 的响应式系统。Vue 团队选择了 v-if 和 v-else 指令作为替代方案,以确保视图更新的准确性和性能。开发者在编写 Vue 组件时应注意这些设计考量,并根据具体情况选择适当的解决方案。