• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ArkCompiler子系统变更说明
2
3## cl.arkcompiler.1 在Array上查找属性以及设置属性的行为变更说明
4
5**访问级别**
6
7公开接口
8
9**变更原因**
10
11ECMAScript 规范中规定,当对某些Array实例进行某些查询,而查询的属性在Array实例自身上不存在时,需遍历原型链来执行查询。由于部分非StableArray的情况被识别为StableArray,导致跳过了原型链查询,查询结果与 ECMAScript 规范所定义的预期结果不一致。
12
13**变更影响**
14
15此变更不涉及应用适配。
16
17**变更前**
18
19- 情况一:当一个对象(o)是Array类型的实例时,通过特定方式(`fill, push, splice, unshift`)修改(Array.prototype),部分接口(`concat, slice, at, reduce, reverse`)无法正确从(o)上读取到(Array.prototype)上的元素,返回错误结果。
20- 情况二:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,(o)上的constructor属性未被正确调用,导致对(o)调用`instance of`时返回结果错误。
21- 情况三:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,修改MyArray.prototype.proto,部分接口(`concat, slice, at, reduce, reverse`)无法正确从(o)上读取到MyArray.prototype.proto上的元素,返回结果错误。
22- 情况四:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,向(MyArray.prototype)中插入元素,部分接口(`concat, slice, at, reduce, reverse`)无法正确从(o)上读取到(MyArray.prototype)上的元素,返回结果错误。
23
24```js
25// 情况一:
26function BehaviorChange1() {
27// 以下有四种方法修改Array.prototype, 效果都是让Array.prototype = [233, 233, 233], 不同代码之间是并列关系
28//  ----------------- 方法1 -----------------
29    let arr1 = new Array(10);
30    arr1.__proto__.length = 3;
31    arr1.__proto__.fill(233, 0, 3);
32//  ----------------- 方法1 -----------------
33
34//  ----------------- 方法2 -----------------
35    let arr1 = new Array(10);
36    arr1.__proto__.push(233, 233, 233);
37//  ----------------- 方法2 -----------------
38
39//  ----------------- 方法3 -----------------
40    let arr1 = new Array(10);
41    arr1.__proto__.length = 3;
42    arr1.__proto__.splice(1, 0, 233, 233, 233);
43//  ----------------- 方法3 -----------------
44
45//  ----------------- 方法4 -----------------
46    let arr1 = new Array(10);
47    arr1.__proto__.unshift(233, 233, 233);
48//  ----------------- 方法4 -----------------
49
50    let arr2 = new Array(10);
51    let arr3 = arr1.concat(arr2);
52    print(arr3[11]); // 输出:undefined,不符合规范
53
54    let arr4 = arr1.slice(1);
55    print(arr4[0]); // 输出:undefined,不符合规范
56
57    let res = arr1.at(1);
58    print(res); // 输出:undefined,不符合规范
59
60    const sum = arr1.reduce((accumulator, currentValue) => {
61        return accumulator + currentValue;
62    })
63    print(sum); // 输出:undefined,不符合规范
64
65    arr1.reverse();
66    print(arr1[1]); //输出: undefined,不符合规范
67}
68BehaviorChange1();
69
70// 情况二:
71function BehaviorChange2() {
72    class MyArray extends Array {}
73    let custom = new MyArray(1, 2, 3);
74    let result1 = custom.concat([4, 5]);
75    print(result1 instanceof MyArray); // 输出:false,不符合规范
76
77    let result2 = custom.slice(1);
78    print(result2 instanceof MyArray); // 输出:false,不符合规范
79}
80BehaviorChange2()
81
82// 情况三:
83function BehaviorChange3() {
84    class MyArray extends Array {}
85    let arr1 = new MyArray(10);
86    MyArray.prototype.__proto__ = [233, 233, 233];
87    let arr2 = new Array(10);
88    let arr3 = arr1.concat(arr2);
89    print(arr3[1]); // 输出:undefined,不符合规范
90
91    let arr4 = arr1.slice(1);
92    print(arr4[0]); // 输出:undefined,不符合规范
93
94    let res = arr1.at(1);
95    print(res); // 输出:undefined,不符合规范
96
97    const sum = arr1.reduce((accumulator, currentValue) => {
98        return accumulator + currentValue;
99    })
100    print(sum); // 输出:undefined,不符合规范
101
102    arr1.reverse();
103    print(arr1[1]); //输出: undefined,不符合规范
104}
105BehaviorChange3();
106
107// 情况四:
108function BehaviorChange4() {
109    class MyArray extends Array {}
110    let arr1 = new MyArray(10);
111    MyArray.prototype[0] = 233;
112    MyArray.prototype[1] = 233;
113    MyArray.prototype[2] = 233;
114
115    let arr2 = new Array(10);
116    let arr3 = arr1.concat(arr2);
117    print(arr3[1]); // 输出:undefined,不符合规范
118
119    let arr4 = arr1.slice(1);
120    print(arr4[0]); // 输出:undefined,不符合规范
121
122    let res = arr1.at(1);
123    print(res); // 输出:undefined,不符合规范
124
125    const sum = arr1.reduce((accumulator, currentValue) => {
126        return accumulator + currentValue;
127    })
128    print(sum); // 输出:undefined,不符合规范
129
130    arr1.reverse();
131    print(arr1[1]); //输出: undefined,不符合规范
132}
133BehaviorChange4();
134```
135**变更后**
136
137- 情况一:当一个对象(o)是Array类型的实例时,通过特定方式(`fill, push, splice, unshift`)修改(Array.prototype),接口(`concat, slice, at, reduce, reverse`)正确从(o)上读取到(Array.prototype)上的元素,返回正确结果(不兼容变更)。
138- 情况二:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,(o)上的constructor属性未被正确调用,对(o)调用`instance of`时返回正确结果(不兼容变更)。
139- 情况三:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,修改MyArray.prototype.proto,接口(`concat, slice, at, reduce, reverse`)正确从(o)上读取到MyArray.prototype.proto上的元素,返回正确结果(不兼容变更)。
140- 情况四:当一个类MyArray继承自Array,对象(o)是MyArray的实例时,向(MyArray.prototype)中插入元素,接口(`concat, slice, at, reduce, reverse`)正确从(o)上读取到(MyArray.prototype)上的元素,返回正确结果(不兼容变更)。
141
142```js
143// 情况一:
144function BehaviorChange1() {
145// 以下有四种方法修改Array.prototype, 效果都是让Array.prototype = [233, 233, 233], 不同代码之间是并列关系
146//  ----------------- 方法1 -----------------
147    let arr1 = new Array(10);
148    arr1.__proto__.length = 3;
149    arr1.__proto__.fill(233, 0, 3);
150//  ----------------- 方法1 -----------------
151
152//  ----------------- 方法2 -----------------
153    let arr1 = new Array(10);
154    arr1.__proto__.push(233, 233, 233);
155//  ----------------- 方法2 -----------------
156
157//  ----------------- 方法3 -----------------
158    let arr1 = new Array(10);
159    arr1.__proto__.length = 3;
160    arr1.__proto__.splice(1, 0, 233, 233, 233);
161//  ----------------- 方法3 -----------------
162
163//  ----------------- 方法4 -----------------
164    let arr1 = new Array(10);
165    arr1.__proto__.unshift(233, 233, 233);
166//  ----------------- 方法4 -----------------
167
168    let arr2 = new Array(10);
169    let arr3 = arr1.concat(arr2);
170    print(arr3[11]); // 输出:233 符合规范,concat的时候当自身没有时会遍历原型链
171
172    let arr4 = arr1.slice(1);
173    print(arr4[0]); // 输出:233 符合规范,slice的时候当自身没有时会遍历原型链
174
175    let res = arr1.at(1);
176    print(res); // 输出:233 符合规范,at的时候当自身没有时会遍历原型链
177
178    const sum = arr1.reduce((accumulator, currentValue) => {
179        return accumulator + currentValue;
180    })
181    print(sum); // 输出:699 符合规范,reduce的时候当自身没有时会遍历原型链
182
183    arr1.reverse();
184    print(arr1[1]); //输出: 233 符合规范,reverse的时候当自身没有时会遍历原型链
185}
186BehaviorChange1();
187
188// 情况二:
189function BehaviorChange2() {
190    class MyArray extends Array {}
191    let custom = new MyArray(1, 2, 3);
192    let result1 = custom.concat([4, 5]);
193    print(result1 instanceof MyArray); // 输出:true 符合规范,custom上的constructor方法被正确调用
194
195    let result2 = custom.slice(1);
196    print(result2 instanceof MyArray); // 输出:true 符合规范,custom上的constructor方法被正确调用
197}
198BehaviorChange2()
199
200// 情况三:
201function BehaviorChange3() {
202    class MyArray extends Array {}
203    let arr1 = new MyArray(10);
204    MyArray.prototype.__proto__ = [233, 233, 233];
205    let arr2 = new Array(10);
206    let arr3 = arr1.concat(arr2);
207    print(arr3[1]); // 输出:233 符合规范,concat的时候当自身没有时会遍历原型链
208
209    let arr4 = arr1.slice(1);
210    print(arr4[0]); // 输出:233 符合规范,slice的时候当自身没有时会遍历原型链
211
212    let res = arr1.at(1);
213    print(res); // 输出:233 符合规范,at的时候当自身没有时会遍历原型链
214
215    const sum = arr1.reduce((accumulator, currentValue) => {
216        return accumulator + currentValue;
217    })
218    print(sum); // 输出:233 符合规范,reduce的时候当自身没有时会遍历原型链
219
220    arr1.reverse();
221    print(arr1[1]); //输出: 233 符合规范,reverse的时候当自身没有时会遍历原型链
222}
223BehaviorChange3();
224
225// 情况四:
226function BehaviorChange4() {
227    class MyArray extends Array {}
228    let arr1 = new MyArray(10);
229    MyArray.prototype[0] = 233;
230    MyArray.prototype[1] = 233;
231    MyArray.prototype[2] = 233;
232
233    let arr2 = new Array(10);
234    let arr3 = arr1.concat(arr2);
235    print(arr3[1]); // 输出:233 符合规范,concat的时候当自身没有时会遍历原型链
236
237    let arr4 = arr1.slice(1);
238    print(arr4[0]); // 输出:233 符合规范,slice的时候当自身没有时会遍历原型链
239
240    let res = arr1.at(1);
241    print(res); // 输出:233 符合规范,at的时候当自身没有时会遍历原型链
242
243    const sum = arr1.reduce((accumulator, currentValue) => {
244        return accumulator + currentValue;
245    })
246    print(sum); // 输出:699 符合规范,reduce的时候当自身没有时会遍历原型链
247
248    arr1.reverse();
249    print(arr1[1]); // 输出: 233 符合规范,reverse的时候当自身没有时会遍历原型链
250}
251BehaviorChange4();
252
253
254```
255
256**起始API Level**
257
258API 9
259
260**变更发生版本**
261
262从OpenHarmony 5.1.0.45 版本开始。
263
264**变更的接口/组件**
265
266涉及Array中`instance of, concat, slice, at, reduce, reverse`接口,详细触发操作见上文。
267
268**适配指导**
269
270在Array上查找属性时注意返回值的变更。
271