ue3
Version:
ue3 build your own vue for learning.
162 lines (133 loc) • 3.48 kB
Markdown
- obj.name
- key: key in obj
- for (key in obj) {}
- set
- add
- delete
拦截方法:get
```typescript
new Proxy(
{},
{
get(target, key, receiver) {
track(target, key);
return Reflect.get(target, key, receiver);
}
}
);
```
明确 in 操作符的运行时逻辑,详细请看 ECMA-262 [ECMA-262 - in](https://262.ecma-international.org/12.0/#sec-relational-operators)
拦截方法:has
```typescript
new Proxy(
{},
{
has(target, key) {
track(target, key);
return Reflect.get(target, key);
}
}
);
```
拦截方法:ownKeys,并为代理对象添加唯一标识 Symbol
```typescript
new Proxy(
{},
{
ownKeys(target, key) {
track(target, ITERATE_KEY);
return Reflect.ownKeys(target, key);
}
}
);
```
拦截方法:set
```typescript
new Proxy(
{},
{
set(target: Record<string, any>, key: string, val: any, receiver) {
const type = Object.prototype.hasOwnProperty.call(target, key)
? "SET"
: "ADD";
const res = Reflect.set(target, key, val, receiver);
trigger(target, key, ITERATE_KEY, type);
return res;
}
}
);
```
拦截方法:set
```typescript
new Proxy(
{},
{
set(target: Record<string, any>, key: string, val: any, receiver) {
const type = Object.prototype.hasOwnProperty.call(target, key)
? "SET"
: "ADD";
const res = Reflect.set(target, key, val, receiver);
trigger(target, key, ITERATE_KEY, type);
return res;
}
}
);
```
拦截方法:deleteProperty
``` typescript
deleteProperty(target: Record<string, any>, key: string) {
const hadKey = Object.prototype.hasOwnProperty.call(target, key);
const res = Reflect.deleteProperty(target, key);
if (res && hadKey) {
trigger(target, key, ITERATE_KEY, 'DELETE');
}
return res;
}
```
- 当值不变的情况下不触发响应
- NaN值的比较 NaN !== NaN // true
- 原型链继承属性的情况 // Reflect 实际上实现了访问属性的默认行为
``` typescript
set(target: T, key: PropertyKey, newVal: any, receiver: any) {
// 旧值
const oldVal = target[key];
const type = Object.prototype.hasOwnProperty.call(target, key) ? 'SET' : 'ADD';
const res = Reflect.set(target, key, newVal, receiver);
if (target === receiver[RAW] && //原型链问题
oldVal !== newVal &&
// 比较新值与旧值,并且都不是NaN的时候才触发响应
(oldVal === oldVal || newVal === newVal)) {
trigger(target, key, ITERATE_KEY, type);
}
return res;
}
```
``` typescript
get(target: T, key: PropertyKey, receiver: any) {
// console.log('get', target, key);
if (key === RAW) {
return target;
}
!option?.readonly && track(target, key);
const res = Reflect.get(target, key, receiver);
if (option?.isShallow) {
return res;
}
if (typeof res === "object" && res !== null) {
return createReactive(res, option, ITERATE_KEY);
}
return res;
}
```