vue-java-tutorials/vue2-tutorials/import-script/3-Object.defineProperty.md

77 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `Object.defineProperty` 方法
## 一、基本概念
`Object.defineProperty()` 是 JavaScript 中用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性的方法。它允许精确控制属性的行为特性。
## 属性描述符详解
### 1. 数据描述符(已注释部分)
```javascript
{
value: 18, // 属性值
enumerable: true, // 是否可枚举for...in或Object.keys()
writable: true, // 是否可修改
configurable: true // 是否可删除或修改特性
}
```
### 2. 存取描述符(实际使用部分)
```javascript
{
get() {
// 读取属性时调用
return age;
},
set(value) {
// 设置属性时调用
age = value;
}
}
```
## 特性说明
| 特性 | 类型 | 默认值 | 描述 |
| ------------ | ---- | --------- | ------------------------ |
| configurable | 布尔 | false | 是否可删除属性或修改特性 |
| enumerable | 布尔 | false | 是否出现在枚举属性中 |
| value | 任意 | undefined | 属性值 |
| writable | 布尔 | false | 是否可被赋值运算符改变 |
| get | 函数 | undefined | 读取属性时调用的函数 |
| set | 函数 | undefined | 设置属性时调用的函数 |
## 使用场景
1. **实现数据响应式**如Vue2的核心实现
2. **创建私有属性**通过getter/setter控制访问
3. **属性访问拦截**(在读取或设置时执行额外操作)
4. **定义不可枚举属性**(如内置对象的一些方法)
## 注意事项
1. 数据描述符value, writable和存取描述符get, set不能同时使用
2. 默认情况下通过defineProperty添加的属性不可枚举、不可写、不可配置
3. 在严格模式下setter必须设置一个参数否则会抛出错误
4. getter不应有副作用如修改其他属性值
**实现简单响应式**
```javascript
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}: ${val}`);
return val;
},
set(newVal) {
console.log(`设置 ${key}: ${newVal}`);
val = newVal;
}
});
}
const data = {};
defineReactive(data, 'message', 'Hello');
```