@feng3d/reactivity 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/assets/RobotoMono-Medium-DVgDz_OO.woff2 +0 -0
  2. package/dist/assets/RobotoMono-Regular-BPoF81uy.woff2 +0 -0
  3. package/dist/assets/index-a2qCSG5V.css +629 -0
  4. package/dist/assets/index.html-Dyp3udP2.js +200 -0
  5. package/dist/assets/modulepreload-polyfill-DaKOjhqt.js +37 -0
  6. package/dist/assets/package-DuJynByc.js +2539 -0
  7. package/dist/assets/src//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274/index.html-C3hbV3IR.js +59 -0
  8. package/dist/assets/src//346/225/260/347/273/204/index.html-CHK6WEhd.js +43 -0
  9. package/dist/docs/.nojekyll +1 -0
  10. package/dist/docs/assets/hierarchy.js +1 -0
  11. package/dist/docs/assets/highlight.css +92 -0
  12. package/dist/docs/assets/icons.js +18 -0
  13. package/dist/docs/assets/icons.svg +1 -0
  14. package/dist/docs/assets/main.js +60 -0
  15. package/dist/docs/assets/navigation.js +1 -0
  16. package/dist/docs/assets/search.js +1 -0
  17. package/dist/docs/assets/style.css +1640 -0
  18. package/dist/docs/classes/EffectScope.html +40 -0
  19. package/dist/docs/functions/batchRun.html +15 -0
  20. package/dist/docs/functions/computed.html +5 -0
  21. package/dist/docs/functions/effect.html +11 -0
  22. package/dist/docs/functions/effectScope.html +5 -0
  23. package/dist/docs/functions/forceTrack.html +6 -0
  24. package/dist/docs/functions/getCurrentScope.html +4 -0
  25. package/dist/docs/functions/isProxy.html +5 -0
  26. package/dist/docs/functions/isReactive.html +5 -0
  27. package/dist/docs/functions/isRef.html +5 -0
  28. package/dist/docs/functions/noTrack.html +6 -0
  29. package/dist/docs/functions/onScopeDispose.html +6 -0
  30. package/dist/docs/functions/reactive.html +19 -0
  31. package/dist/docs/functions/ref.html +13 -0
  32. package/dist/docs/functions/toRaw.html +4 -0
  33. package/dist/docs/hierarchy.html +1 -0
  34. package/dist/docs/index.html +129 -0
  35. package/dist/docs/interfaces/Computed.html +9 -0
  36. package/dist/docs/interfaces/Effect.html +8 -0
  37. package/dist/docs/interfaces/Ref.html +9 -0
  38. package/dist/docs/modules.html +1 -0
  39. package/dist/docs/types/Reactive.html +3 -0
  40. package/dist/docs/types/UnReadonly.html +3 -0
  41. package/dist/files/RobotoMono-Medium.woff2 +0 -0
  42. package/dist/files/RobotoMono-Regular.woff2 +0 -0
  43. package/dist/files/ic_code_black_24dp.svg +4 -0
  44. package/dist/files/ic_search_black_24dp.svg +4 -0
  45. package/dist/files/main.css +629 -0
  46. package/dist/files/thumbnails.svg +7 -0
  47. package/dist/files.json +7 -0
  48. package/dist/index.html +84 -0
  49. package/dist/index.js +733 -157
  50. package/dist/index.js.map +1 -1
  51. package/dist/index.umd.cjs +733 -157
  52. package/dist/index.umd.cjs.map +1 -1
  53. package/dist/screenshots//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274.jpg +0 -0
  54. package/dist/screenshots//346/225/260/347/273/204.jpg +0 -0
  55. package/dist/src//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274/index.html +70 -0
  56. package/dist/src//346/225/260/347/273/204/index.html +65 -0
  57. package/dist/tags.json +2 -0
  58. package/lib/Reactivity.d.ts +47 -13
  59. package/lib/Reactivity.d.ts.map +1 -1
  60. package/lib/arrayInstrumentations.d.ts +10 -0
  61. package/lib/arrayInstrumentations.d.ts.map +1 -1
  62. package/lib/baseHandlers.d.ts +3 -1
  63. package/lib/baseHandlers.d.ts.map +1 -1
  64. package/lib/batch.d.ts +17 -5
  65. package/lib/batch.d.ts.map +1 -1
  66. package/lib/collectionHandlers.d.ts +21 -0
  67. package/lib/collectionHandlers.d.ts.map +1 -1
  68. package/lib/computed.d.ts +75 -27
  69. package/lib/computed.d.ts.map +1 -1
  70. package/lib/effect.d.ts +25 -0
  71. package/lib/effect.d.ts.map +1 -1
  72. package/lib/effectScope.d.ts +129 -0
  73. package/lib/effectScope.d.ts.map +1 -0
  74. package/lib/index.d.ts +6 -5
  75. package/lib/index.d.ts.map +1 -1
  76. package/lib/property.d.ts.map +1 -1
  77. package/lib/reactive.d.ts +58 -17
  78. package/lib/reactive.d.ts.map +1 -1
  79. package/lib/ref.d.ts +66 -4
  80. package/lib/ref.d.ts.map +1 -1
  81. package/lib/shared/constants.d.ts +7 -7
  82. package/lib/shared/constants.d.ts.map +1 -1
  83. package/lib/shared/general.d.ts +1 -1
  84. package/lib/shared/general.d.ts.map +1 -1
  85. package/package.json +19 -17
  86. package/src/Reactivity.ts +57 -15
  87. package/src/arrayInstrumentations.ts +406 -53
  88. package/src/baseHandlers.ts +124 -32
  89. package/src/batch.ts +38 -11
  90. package/src/collectionHandlers.ts +207 -19
  91. package/src/computed.ts +92 -43
  92. package/src/effect.ts +38 -0
  93. package/src/effectScope.ts +294 -0
  94. package/src/index.ts +6 -5
  95. package/src/property.ts +6 -0
  96. package/src/reactive.ts +67 -20
  97. package/src/ref.ts +66 -4
@@ -7,11 +7,28 @@ import { isProxy, toReactive } from './reactive';
7
7
  import { ARRAY_ITERATE_KEY, TrackOpTypes } from './shared/constants';
8
8
  import { isArray, toRaw } from './shared/general';
9
9
 
10
+ /**
11
+ * 数组方法增强对象。
12
+ *
13
+ * 为数组提供响应式增强的方法实现,包括:
14
+ * 1. 迭代器方法:Symbol.iterator、entries、keys、values
15
+ * 2. 查找方法:includes、indexOf、lastIndexOf、find、findIndex、findLast、findLastIndex
16
+ * 3. 遍历方法:forEach、map、filter、some、every、reduce、reduceRight
17
+ * 4. 修改方法:push、pop、shift、unshift、splice、toReversed、toSorted、toSpliced
18
+ * 5. 其他方法:concat、join
19
+ */
10
20
  export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
11
21
  __proto__: null,
12
22
 
13
23
  /**
14
- * 返回一个迭代器,用于遍历数组的响应式值
24
+ * 返回一个迭代器,用于遍历数组的响应式值。
25
+ *
26
+ * 实现了以下功能:
27
+ * 1. 创建数组的迭代器
28
+ * 2. 自动将迭代的值转换为响应式
29
+ * 3. 自动追踪数组的访问
30
+ *
31
+ * @returns 数组的迭代器
15
32
  */
16
33
  [Symbol.iterator]()
17
34
  {
@@ -19,7 +36,15 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
19
36
  },
20
37
 
21
38
  /**
22
- * 连接数组并返回新数组,处理响应式数组
39
+ * 连接数组并返回新数组。
40
+ *
41
+ * 实现了以下功能:
42
+ * 1. 处理响应式数组的连接
43
+ * 2. 自动将参数中的数组转换为响应式
44
+ * 3. 保持原始值的引用
45
+ *
46
+ * @param args 要连接的数组或值
47
+ * @returns 连接后的新数组
23
48
  */
24
49
  concat(...args: unknown[])
25
50
  {
@@ -29,7 +54,14 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
29
54
  },
30
55
 
31
56
  /**
32
- * 返回一个迭代器,用于遍历数组的键值对,并将值转换为响应式
57
+ * 返回一个迭代器,用于遍历数组的键值对。
58
+ *
59
+ * 实现了以下功能:
60
+ * 1. 创建数组的键值对迭代器
61
+ * 2. 自动将值转换为响应式
62
+ * 3. 自动追踪数组的访问
63
+ *
64
+ * @returns 数组的键值对迭代器
33
65
  */
34
66
  entries()
35
67
  {
@@ -42,7 +74,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
42
74
  },
43
75
 
44
76
  /**
45
- * 测试数组中的所有元素是否都通过了指定函数的测试
77
+ * 测试数组中的所有元素是否都通过了指定函数的测试。
78
+ *
79
+ * 实现了以下功能:
80
+ * 1. 遍历数组元素
81
+ * 2. 对每个元素执行测试函数
82
+ * 3. 自动追踪数组的访问
83
+ * 4. 处理响应式值的测试
84
+ *
85
+ * @param fn 测试函数
86
+ * @param thisArg 测试函数的 this 值
87
+ * @returns 如果所有元素都通过测试则返回 true,否则返回 false
46
88
  */
47
89
  every(fn: (item: unknown, index: number, array: unknown[]) => unknown,
48
90
  thisArg?: unknown,
@@ -52,7 +94,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
52
94
  },
53
95
 
54
96
  /**
55
- * 创建一个新数组,包含通过指定函数测试的所有元素
97
+ * 创建一个新数组,包含通过指定函数测试的所有元素。
98
+ *
99
+ * 实现了以下功能:
100
+ * 1. 遍历数组元素
101
+ * 2. 对每个元素执行测试函数
102
+ * 3. 自动追踪数组的访问
103
+ * 4. 自动将结果转换为响应式
104
+ *
105
+ * @param fn 测试函数
106
+ * @param thisArg 测试函数的 this 值
107
+ * @returns 包含通过测试的元素的新数组
56
108
  */
57
109
  filter(fn: (item: unknown, index: number, array: unknown[]) => unknown,
58
110
  thisArg?: unknown,
@@ -62,7 +114,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
62
114
  },
63
115
 
64
116
  /**
65
- * 返回数组中满足指定测试函数的第一个元素
117
+ * 返回数组中满足指定测试函数的第一个元素。
118
+ *
119
+ * 实现了以下功能:
120
+ * 1. 遍历数组元素
121
+ * 2. 对每个元素执行测试函数
122
+ * 3. 自动追踪数组的访问
123
+ * 4. 自动将结果转换为响应式
124
+ *
125
+ * @param fn 测试函数
126
+ * @param thisArg 测试函数的 this 值
127
+ * @returns 第一个满足测试的元素,如果没有则返回 undefined
66
128
  */
67
129
  find(fn: (item: unknown, index: number, array: unknown[]) => boolean,
68
130
  thisArg?: unknown,
@@ -72,7 +134,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
72
134
  },
73
135
 
74
136
  /**
75
- * 返回数组中满足指定测试函数的第一个元素的索引
137
+ * 返回数组中满足指定测试函数的第一个元素的索引。
138
+ *
139
+ * 实现了以下功能:
140
+ * 1. 遍历数组元素
141
+ * 2. 对每个元素执行测试函数
142
+ * 3. 自动追踪数组的访问
143
+ * 4. 处理响应式值的查找
144
+ *
145
+ * @param fn 测试函数
146
+ * @param thisArg 测试函数的 this 值
147
+ * @returns 第一个满足测试的元素的索引,如果没有则返回 -1
76
148
  */
77
149
  findIndex(fn: (item: unknown, index: number, array: unknown[]) => boolean,
78
150
  thisArg?: unknown,
@@ -82,7 +154,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
82
154
  },
83
155
 
84
156
  /**
85
- * 返回数组中满足指定测试函数的最后一个元素
157
+ * 返回数组中满足指定测试函数的最后一个元素。
158
+ *
159
+ * 实现了以下功能:
160
+ * 1. 从后向前遍历数组元素
161
+ * 2. 对每个元素执行测试函数
162
+ * 3. 自动追踪数组的访问
163
+ * 4. 自动将结果转换为响应式
164
+ *
165
+ * @param fn 测试函数
166
+ * @param thisArg 测试函数的 this 值
167
+ * @returns 最后一个满足测试的元素,如果没有则返回 undefined
86
168
  */
87
169
  findLast(fn: (item: unknown, index: number, array: unknown[]) => boolean,
88
170
  thisArg?: unknown,
@@ -92,7 +174,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
92
174
  },
93
175
 
94
176
  /**
95
- * 返回数组中满足指定测试函数的最后一个元素的索引
177
+ * 返回数组中满足指定测试函数的最后一个元素的索引。
178
+ *
179
+ * 实现了以下功能:
180
+ * 1. 从后向前遍历数组元素
181
+ * 2. 对每个元素执行测试函数
182
+ * 3. 自动追踪数组的访问
183
+ * 4. 处理响应式值的查找
184
+ *
185
+ * @param fn 测试函数
186
+ * @param thisArg 测试函数的 this 值
187
+ * @returns 最后一个满足测试的元素的索引,如果没有则返回 -1
96
188
  */
97
189
  findLastIndex(fn: (item: unknown, index: number, array: unknown[]) => boolean,
98
190
  thisArg?: unknown,
@@ -101,10 +193,19 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
101
193
  return apply(this, 'findLastIndex', fn, thisArg, undefined, arguments);
102
194
  },
103
195
 
104
- // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement
196
+ // flat, flatMap 可以从 ARRAY_ITERATE 中受益,但实现起来不太直接
105
197
 
106
198
  /**
107
- * 对数组中的每个元素执行指定函数
199
+ * 对数组中的每个元素执行指定函数。
200
+ *
201
+ * 实现了以下功能:
202
+ * 1. 遍历数组元素
203
+ * 2. 对每个元素执行回调函数
204
+ * 3. 自动追踪数组的访问
205
+ * 4. 处理响应式值的遍历
206
+ *
207
+ * @param fn 回调函数
208
+ * @param thisArg 回调函数的 this 值
108
209
  */
109
210
  forEach(fn: (item: unknown, index: number, array: unknown[]) => unknown,
110
211
  thisArg?: unknown,
@@ -114,15 +215,31 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
114
215
  },
115
216
 
116
217
  /**
117
- * 判断数组是否包含指定元素,处理响应式值
218
+ * 判断数组是否包含指定元素。
219
+ *
220
+ * 实现了以下功能:
221
+ * 1. 处理响应式值的查找
222
+ * 2. 自动追踪数组的访问
223
+ * 3. 处理代理对象的查找
224
+ *
225
+ * @param args 要查找的元素
226
+ * @returns 如果数组包含该元素则返回 true,否则返回 false
118
227
  */
119
228
  includes(...args: unknown[])
120
229
  {
121
- return searchProxy(this, 'includes', args);
230
+ return searchProxy(this, 'includes' as any, args);
122
231
  },
123
232
 
124
233
  /**
125
- * 返回数组中指定元素第一次出现的索引,处理响应式值
234
+ * 返回数组中指定元素第一次出现的索引。
235
+ *
236
+ * 实现了以下功能:
237
+ * 1. 处理响应式值的查找
238
+ * 2. 自动追踪数组的访问
239
+ * 3. 处理代理对象的查找
240
+ *
241
+ * @param args 要查找的元素
242
+ * @returns 元素第一次出现的索引,如果没有则返回 -1
126
243
  */
127
244
  indexOf(...args: unknown[])
128
245
  {
@@ -130,17 +247,33 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
130
247
  },
131
248
 
132
249
  /**
133
- * 将数组的所有元素连接成一个字符串
250
+ * 将数组的所有元素连接成一个字符串。
251
+ *
252
+ * 实现了以下功能:
253
+ * 1. 处理响应式数组的连接
254
+ * 2. 自动追踪数组的访问
255
+ * 3. 保持原始值的引用
256
+ *
257
+ * @param separator 分隔符
258
+ * @returns 连接后的字符串
134
259
  */
135
260
  join(separator?: string)
136
261
  {
137
262
  return reactiveReadArray(this).join(separator);
138
263
  },
139
264
 
140
- // keys() iterator only reads `length`, no optimisation required
265
+ // keys() 迭代器只读取 length,不需要优化
141
266
 
142
267
  /**
143
- * 返回数组中指定元素最后一次出现的索引,处理响应式值
268
+ * 返回数组中指定元素最后一次出现的索引。
269
+ *
270
+ * 实现了以下功能:
271
+ * 1. 处理响应式值的查找
272
+ * 2. 自动追踪数组的访问
273
+ * 3. 处理代理对象的查找
274
+ *
275
+ * @param args 要查找的元素
276
+ * @returns 元素最后一次出现的索引,如果没有则返回 -1
144
277
  */
145
278
  lastIndexOf(...args: unknown[])
146
279
  {
@@ -148,7 +281,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
148
281
  },
149
282
 
150
283
  /**
151
- * 创建一个新数组,包含对原数组每个元素调用指定函数的结果
284
+ * 创建一个新数组,包含对原数组每个元素调用指定函数的结果。
285
+ *
286
+ * 实现了以下功能:
287
+ * 1. 遍历数组元素
288
+ * 2. 对每个元素执行映射函数
289
+ * 3. 自动追踪数组的访问
290
+ * 4. 处理响应式值的映射
291
+ *
292
+ * @param fn 映射函数
293
+ * @param thisArg 映射函数的 this 值
294
+ * @returns 包含映射结果的新数组
152
295
  */
153
296
  map(fn: (item: unknown, index: number, array: unknown[]) => unknown,
154
297
  thisArg?: unknown,
@@ -158,7 +301,14 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
158
301
  },
159
302
 
160
303
  /**
161
- * 移除数组的最后一个元素并返回该元素,避免跟踪长度变化
304
+ * 移除数组的最后一个元素并返回该元素。
305
+ *
306
+ * 实现了以下功能:
307
+ * 1. 移除最后一个元素
308
+ * 2. 避免跟踪长度变化
309
+ * 3. 处理响应式值的移除
310
+ *
311
+ * @returns 被移除的元素
162
312
  */
163
313
  pop()
164
314
  {
@@ -166,7 +316,15 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
166
316
  },
167
317
 
168
318
  /**
169
- * 向数组末尾添加一个或多个元素,并返回新的长度,避免跟踪长度变化
319
+ * 向数组末尾添加一个或多个元素。
320
+ *
321
+ * 实现了以下功能:
322
+ * 1. 添加新元素
323
+ * 2. 避免跟踪长度变化
324
+ * 3. 处理响应式值的添加
325
+ *
326
+ * @param args 要添加的元素
327
+ * @returns 数组的新长度
170
328
  */
171
329
  push(...args: unknown[])
172
330
  {
@@ -174,7 +332,17 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
174
332
  },
175
333
 
176
334
  /**
177
- * 对数组中的每个元素执行累加器函数,并返回最终结果
335
+ * 对数组中的每个元素执行累加器函数。
336
+ *
337
+ * 实现了以下功能:
338
+ * 1. 从左到右遍历数组元素
339
+ * 2. 对每个元素执行累加器函数
340
+ * 3. 自动追踪数组的访问
341
+ * 4. 处理响应式值的累加
342
+ *
343
+ * @param fn 累加器函数
344
+ * @param args 初始值(可选)
345
+ * @returns 累加的结果
178
346
  */
179
347
  reduce(fn: (
180
348
  acc: unknown,
@@ -182,14 +350,24 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
182
350
  index: number,
183
351
  array: unknown[],
184
352
  ) => unknown,
185
- ...args: unknown[]
353
+ ...args: unknown[]
186
354
  )
187
355
  {
188
356
  return reduce(this, 'reduce', fn, args);
189
357
  },
190
358
 
191
359
  /**
192
- * 从右到左对数组中的每个元素执行累加器函数,并返回最终结果
360
+ * 从右到左对数组中的每个元素执行累加器函数。
361
+ *
362
+ * 实现了以下功能:
363
+ * 1. 从右到左遍历数组元素
364
+ * 2. 对每个元素执行累加器函数
365
+ * 3. 自动追踪数组的访问
366
+ * 4. 处理响应式值的累加
367
+ *
368
+ * @param fn 累加器函数
369
+ * @param args 初始值(可选)
370
+ * @returns 累加的结果
193
371
  */
194
372
  reduceRight(
195
373
  fn: (
@@ -205,17 +383,34 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
205
383
  },
206
384
 
207
385
  /**
208
- * 移除数组的第一个元素并返回该元素,避免跟踪长度变化
386
+ * 移除数组的第一个元素并返回该元素。
387
+ *
388
+ * 实现了以下功能:
389
+ * 1. 移除第一个元素
390
+ * 2. 避免跟踪长度变化
391
+ * 3. 处理响应式值的移除
392
+ *
393
+ * @returns 被移除的元素
209
394
  */
210
395
  shift()
211
396
  {
212
397
  return noTracking(this, 'shift');
213
398
  },
214
399
 
215
- // slice could use ARRAY_ITERATE but also seems to beg for range tracking
400
+ // slice 可以使用 ARRAY_ITERATE,但似乎也需要范围追踪
216
401
 
217
402
  /**
218
- * 测试数组中的某些元素是否通过了指定函数的测试
403
+ * 测试数组中的某些元素是否通过了指定函数的测试。
404
+ *
405
+ * 实现了以下功能:
406
+ * 1. 遍历数组元素
407
+ * 2. 对每个元素执行测试函数
408
+ * 3. 自动追踪数组的访问
409
+ * 4. 处理响应式值的测试
410
+ *
411
+ * @param fn 测试函数
412
+ * @param thisArg 测试函数的 this 值
413
+ * @returns 如果有元素通过测试则返回 true,否则返回 false
219
414
  */
220
415
  some(
221
416
  fn: (item: unknown, index: number, array: unknown[]) => unknown,
@@ -226,7 +421,15 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
226
421
  },
227
422
 
228
423
  /**
229
- * 通过删除或替换现有元素或添加新元素来修改数组,避免跟踪长度变化
424
+ * 通过删除或替换现有元素或添加新元素来修改数组。
425
+ *
426
+ * 实现了以下功能:
427
+ * 1. 修改数组内容
428
+ * 2. 避免跟踪长度变化
429
+ * 3. 处理响应式值的修改
430
+ *
431
+ * @param args 要删除的起始索引、要删除的元素数量和要添加的元素
432
+ * @returns 包含被删除元素的新数组
230
433
  */
231
434
  splice(...args: unknown[])
232
435
  {
@@ -234,7 +437,14 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
234
437
  },
235
438
 
236
439
  /**
237
- * 返回一个新数组,包含原数组的反转副本
440
+ * 返回一个新数组,包含原数组的反转副本。
441
+ *
442
+ * 实现了以下功能:
443
+ * 1. 创建数组的反转副本
444
+ * 2. 自动将结果转换为响应式
445
+ * 3. 保持原始值的引用
446
+ *
447
+ * @returns 反转后的新数组
238
448
  */
239
449
  toReversed()
240
450
  {
@@ -243,7 +453,15 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
243
453
  },
244
454
 
245
455
  /**
246
- * 返回一个新数组,包含原数组的排序副本
456
+ * 返回一个新数组,包含原数组的排序副本。
457
+ *
458
+ * 实现了以下功能:
459
+ * 1. 创建数组的排序副本
460
+ * 2. 自动将结果转换为响应式
461
+ * 3. 保持原始值的引用
462
+ *
463
+ * @param comparer 比较函数
464
+ * @returns 排序后的新数组
247
465
  */
248
466
  toSorted(comparer?: (a: unknown, b: unknown) => number)
249
467
  {
@@ -252,16 +470,32 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
252
470
  },
253
471
 
254
472
  /**
255
- * 返回一个新数组,包含原数组的切片副本
473
+ * 返回一个新数组,包含原数组的切片副本。
474
+ *
475
+ * 实现了以下功能:
476
+ * 1. 创建数组的切片副本
477
+ * 2. 自动将结果转换为响应式
478
+ * 3. 保持原始值的引用
479
+ *
480
+ * @param args 起始索引和结束索引
481
+ * @returns 切片后的新数组
256
482
  */
257
483
  toSpliced(...args: unknown[])
258
484
  {
259
485
  // @ts-expect-error user code may run in es2016+
260
- return (reactiveReadArray(this).toSpliced as any)(...args);
486
+ return reactiveReadArray(this).toSpliced(...args);
261
487
  },
262
488
 
263
489
  /**
264
- * 向数组开头添加一个或多个元素,并返回新的长度,避免跟踪长度变化
490
+ * 向数组开头添加一个或多个元素。
491
+ *
492
+ * 实现了以下功能:
493
+ * 1. 添加新元素
494
+ * 2. 避免跟踪长度变化
495
+ * 3. 处理响应式值的添加
496
+ *
497
+ * @param args 要添加的元素
498
+ * @returns 数组的新长度
265
499
  */
266
500
  unshift(...args: unknown[])
267
501
  {
@@ -269,7 +503,14 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
269
503
  },
270
504
 
271
505
  /**
272
- * 返回一个迭代器,用于遍历数组的响应式值
506
+ * 返回一个迭代器,用于遍历数组的值。
507
+ *
508
+ * 实现了以下功能:
509
+ * 1. 创建数组的值迭代器
510
+ * 2. 自动将迭代的值转换为响应式
511
+ * 3. 自动追踪数组的访问
512
+ *
513
+ * @returns 数组的值迭代器
273
514
  */
274
515
  values()
275
516
  {
@@ -277,31 +518,45 @@ export const arrayInstrumentations: Record<string | symbol, Function> = <any>{
277
518
  },
278
519
  };
279
520
 
280
- // instrument iterators to take ARRAY_ITERATE dependency
521
+ /**
522
+ * 创建数组的迭代器。
523
+ *
524
+ * 实现了以下功能:
525
+ * 1. 创建数组的迭代器
526
+ * 2. 自动将迭代的值转换为响应式
527
+ * 3. 自动追踪数组的访问
528
+ *
529
+ * 注意:在这里获取 ARRAY_ITERATE 依赖并不完全等同于在代理数组上调用迭代。
530
+ * 创建迭代器时不会访问任何数组属性:
531
+ * 只有在调用 .next() 时才会访问 length 和索引。
532
+ * 从极端情况来看,迭代器可以在一个 effect scope 中创建,
533
+ * 在另一个 scope 中部分迭代,然后在第三个 scope 中继续迭代。
534
+ * 考虑到 JS 迭代器只能读取一次,这似乎不是一个合理的用例,
535
+ * 所以这种跟踪简化是可以接受的。
536
+ *
537
+ * @param self 目标数组
538
+ * @param method 迭代器方法名
539
+ * @param wrapValue 值包装函数,用于将值转换为响应式
540
+ * @returns 数组的迭代器
541
+ */
281
542
  function iterator(
282
543
  self: unknown[],
283
544
  method: keyof Array<unknown>,
284
545
  wrapValue: (value: any) => unknown,
285
546
  )
286
547
  {
287
- // note that taking ARRAY_ITERATE dependency here is not strictly equivalent
288
- // to calling iterate on the proxified array.
289
- // creating the iterator does not access any array property:
290
- // it is only when .next() is called that length and indexes are accessed.
291
- // pushed to the extreme, an iterator could be created in one effect scope,
292
- // partially iterated in another, then iterated more in yet another.
293
- // given that JS iterator can only be read once, this doesn't seem like
294
- // a plausible use-case, so this tracking simplification seems ok.
295
548
  const arr = shallowReadArray(self);
296
549
  const iter = (arr[method] as any)() as IterableIterator<unknown> & {
297
550
  _next: IterableIterator<unknown>['next']
298
551
  };
552
+
299
553
  if (arr !== self)
300
554
  {
301
555
  iter._next = iter.next;
302
556
  iter.next = () =>
303
557
  {
304
558
  const result = iter._next();
559
+
305
560
  if (result.value)
306
561
  {
307
562
  result.value = wrapValue(result.value);
@@ -315,7 +570,17 @@ function iterator(
315
570
  }
316
571
 
317
572
  /**
318
- * 跟踪数组的迭代操作并返回原始数组
573
+ * 创建数组的浅层响应式副本。
574
+ *
575
+ * 实现了以下功能:
576
+ * 1. 跟踪数组的迭代操作
577
+ * 2. 返回原始数组的引用
578
+ *
579
+ * 注意:此函数只跟踪数组的迭代操作,不会递归转换数组中的值。
580
+ * 主要用于优化性能,避免不必要的响应式转换。
581
+ *
582
+ * @param arr 目标数组
583
+ * @returns 数组的浅层响应式副本
319
584
  */
320
585
  function shallowReadArray<T>(arr: T[]): T[]
321
586
  {
@@ -324,21 +589,59 @@ function shallowReadArray<T>(arr: T[]): T[]
324
589
  return arr;
325
590
  }
326
591
 
592
+ /**
593
+ * 创建数组的深层响应式副本。
594
+ *
595
+ * 实现了以下功能:
596
+ * 1. 跟踪数组的迭代操作
597
+ * 2. 递归转换所有值为响应式
598
+ *
599
+ * 注意:此函数会递归转换数组中的所有值为响应式,
600
+ * 包括嵌套的数组和对象。这可能会导致性能开销,
601
+ * 但确保了所有值都是响应式的。
602
+ *
603
+ * @param array 目标数组
604
+ * @returns 数组的深层响应式副本
605
+ */
327
606
  function reactiveReadArray<T>(array: T[]): T[]
328
607
  {
329
608
  const raw = toRaw(array);
609
+
330
610
  if (raw === array) return raw;
331
611
  PropertyReactivity.track(raw, TrackOpTypes.ITERATE, ARRAY_ITERATE_KEY);
332
612
 
333
613
  return raw.map(toReactive);
334
614
  }
335
615
 
336
- // in the codebase we enforce es2016, but user code may run in environments
337
- // higher than that
616
+ /**
617
+ * 数组方法类型。
618
+ *
619
+ * 包括所有需要增强的数组方法。
620
+ * 注意:在代码库中我们强制使用 es2016,但用户代码可能在更高版本的环境中运行。
621
+ */
338
622
  type ArrayMethods = keyof Array<any> | 'findLast' | 'findLastIndex';
339
623
 
340
- // instrument functions that read (potentially) all items
341
- // to take ARRAY_ITERATE dependency
624
+ /**
625
+ * 应用数组方法。
626
+ *
627
+ * 实现了以下功能:
628
+ * 1. 调用数组方法
629
+ * 2. 自动追踪数组的访问
630
+ * 3. 处理回调函数的执行
631
+ * 4. 处理返回值的转换
632
+ *
633
+ * 注意:如果调用的方法来自用户扩展的 Array,参数将是未知的
634
+ * (未知顺序和未知参数类型)。在这种情况下,我们跳过 shallowReadArray
635
+ * 处理,直接使用 self 调用 apply。
636
+ *
637
+ * @param self 目标数组
638
+ * @param method 方法名
639
+ * @param fn 回调函数
640
+ * @param thisArg 回调函数的 this 值
641
+ * @param wrappedRetFn 返回值包装函数,用于将返回值转换为响应式
642
+ * @param args 方法参数
643
+ * @returns 方法的执行结果
644
+ */
342
645
  function apply(
343
646
  self: unknown[],
344
647
  method: ArrayMethods,
@@ -364,6 +667,7 @@ function apply(
364
667
  }
365
668
 
366
669
  let wrappedFn = fn;
670
+
367
671
  if (arr !== self)
368
672
  {
369
673
  if (needsWrap)
@@ -386,7 +690,24 @@ function apply(
386
690
  return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result;
387
691
  }
388
692
 
389
- // instrument reduce and reduceRight to take ARRAY_ITERATE dependency
693
+ /**
694
+ * 应用数组的归约方法。
695
+ *
696
+ * 实现了以下功能:
697
+ * 1. 调用数组的归约方法
698
+ * 2. 自动追踪数组的访问
699
+ * 3. 处理回调函数的执行
700
+ * 4. 处理响应式值的归约
701
+ *
702
+ * 注意:此函数用于处理 reduce 和 reduceRight 方法,
703
+ * 确保在归约过程中正确处理响应式值。
704
+ *
705
+ * @param self 目标数组
706
+ * @param method 方法名('reduce' 或 'reduceRight')
707
+ * @param fn 归约函数
708
+ * @param args 方法参数,包括初始值(可选)
709
+ * @returns 归约的结果
710
+ */
390
711
  function reduce(
391
712
  self: unknown[],
392
713
  method: keyof Array<any>,
@@ -396,6 +717,7 @@ function reduce(
396
717
  {
397
718
  const arr = shallowReadArray(self);
398
719
  let wrappedFn = fn;
720
+
399
721
  if (arr !== self)
400
722
  {
401
723
  wrappedFn = function (this: unknown, acc, item, index)
@@ -407,7 +729,23 @@ function reduce(
407
729
  return (arr[method] as any)(wrappedFn, ...args);
408
730
  }
409
731
 
410
- // instrument identity-sensitive methods to account for reactive proxies
732
+ /**
733
+ * 在数组中搜索元素。
734
+ *
735
+ * 实现了以下功能:
736
+ * 1. 处理响应式值的搜索
737
+ * 2. 自动追踪数组的访问
738
+ * 3. 处理代理对象的搜索
739
+ *
740
+ * 注意:我们首先使用原始参数(可能是响应式的)运行方法。
741
+ * 如果那不起作用,我们再次使用原始值运行。
742
+ * 这确保了在搜索响应式值时能够正确处理。
743
+ *
744
+ * @param self 目标数组
745
+ * @param method 方法名('includes'、'indexOf' 或 'lastIndexOf')
746
+ * @param args 搜索参数
747
+ * @returns 搜索的结果(布尔值或索引)
748
+ */
411
749
  function searchProxy(
412
750
  self: unknown[],
413
751
  method: keyof Array<any>,
@@ -415,6 +753,7 @@ function searchProxy(
415
753
  )
416
754
  {
417
755
  const arr = toRaw(self) as any;
756
+
418
757
  PropertyReactivity.track(arr, TrackOpTypes.ITERATE, ARRAY_ITERATE_KEY);
419
758
  // we run the method using the original args first (which may be reactive)
420
759
  const res = arr[method](...args);
@@ -430,8 +769,22 @@ function searchProxy(
430
769
  return res;
431
770
  }
432
771
 
433
- // instrument length-altering mutation methods to avoid length being tracked
434
- // which leads to infinite loops in some cases (#2137)
772
+ /**
773
+ * 执行不跟踪的数组操作。
774
+ *
775
+ * 实现了以下功能:
776
+ * 1. 执行数组操作
777
+ * 2. 避免跟踪长度变化
778
+ * 3. 在批处理中执行操作
779
+ *
780
+ * 注意:这用于避免在某些情况下(#2137)由于跟踪长度变化而导致的无限循环。
781
+ * 通过使用批处理和禁用跟踪,我们可以安全地执行这些操作。
782
+ *
783
+ * @param self 目标数组
784
+ * @param method 方法名('push'、'pop'、'shift'、'unshift' 或 'splice')
785
+ * @param args 方法参数
786
+ * @returns 操作的执行结果
787
+ */
435
788
  function noTracking(
436
789
  self: unknown[],
437
790
  method: keyof Array<any>,
@@ -440,8 +793,8 @@ function noTracking(
440
793
  {
441
794
  const res = batchRun(() =>
442
795
  noTrack(() =>
443
- (toRaw(self) as any)[method].apply(self, args)
444
- )
796
+ (toRaw(self) as any)[method].apply(self, args),
797
+ ),
445
798
  );
446
799
 
447
800
  return res;