• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ArkCompiler子系统变更说明
2
3## cl.arkcompiler.1 在TypedArray上查找属性以及设置属性的行为变更说明
4
5**访问级别**
6
7公开接口
8
9**变更原因**
10
11ECMAScript规范中规定了对于在JS对象上调用`Reflect.set`以及`[[HasProperty]]`的行为,这两个函数涉及到遍历原型链的过程。
12当遍历原型链过程涉及到TypedArray对象时,当前的运行时实现导致运行返回结果与规范定义的预期结果不一致。
13
14**变更影响**
15
16该变更为不兼容变更。
17
18**变更前**
19
20- 情况一:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,如果查找的key是一个大于(ta)的长度的下标,属性判断会返回错误结果。
21- 情况二:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,如果查找的key是一个Number类型,且这个key在(ta)的原型对象上时,属性判断会返回错误结果。
22- 情况三:通过`Reflect.set`向一个对象(o)中的某个属性key设置值value,本地调用的参数中的`receiver`是一个TypedArray类型的对象(ta),如果属性key是一个NumbericIndex类型且其值大于(ta)的长度时,`Reflect.set`返回错误的结果。
23
24```js
25// 情况一:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,查找的key是一个大于(ta)的长度的下标
26function BehaviorChange1() {
27    // 以Int8Array为例创建一个TypedArray对象
28    const typedArray = new Int8Array(5);
29    typedArray[1] = 42;
30
31    // 创建一个Object对象,并将它的原型设置为TypedArray对象
32    const obj = Object.create(typedArray);
33    // 查找Object对象上是否有"6"这个属性的时候,遍历原型链查找
34    print(6 in obj); // 输出:true
35}
36BehaviorChange1();
37
38// 情况二:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,查找的key是一个NumbericIndex类型,且这个key在(ta)的原型对象上
39function BehaviorChange2() {
40    // 创建一个普通的Object对象,持有属性"6"
41    const obj1 = {};
42    obj1[6] = "b";
43
44    // 以Int8Array为例创建一个TypedArray对象
45    const typedArray = new Int8Array(5);
46    typedArray[1] = 42;
47    // 将typedArray的原型设置为第一步创建的obj1对象
48    typedArray.__proto__ = obj1;
49
50    // 创建一个Object对象,并将它的原型设置为TypedArray对象
51    const obj = Object.create(typedArray);
52    // 查找Object对象上是否有"6"这个属性的时候,遍历原型链查找
53    print("6" in obj); // 输出:true
54}
55BehaviorChange2()
56
57// 情况三:通过`Reflect.set`向一个对象(o)中的某个属性key设置值value,本地调用的参数中的`receiver`是一个TypedArray类型的对象(ta),属性key是一个NumbericIndex类型且其值大于(ta)的长度
58function BehaviorChange3() {
59    // 第二个参数是propKey,第三个参数是value,第四个参数是receiver
60    print(Reflect.set({}, 100, 123, new Int32Array())); // 输出:true
61}
62BehaviorChange3();
63```
64
65**变更后**
66
67- 情况一:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,如果查找的key是一个大于(ta)的长度的下标,属性返回正确结果(不兼容变更)。
68- 情况二:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,如果查找的key是一个NumbericIndex类型,且这个key在(ta)的原型对象上时,属性判断返回正确结果(不兼容变更)。
69- 情况三:通过`Reflect.set`向一个对象(o)中的某个属性key设置值value,本地调用的参数中的`receiver`是一个TypedArray类型的对象(ta),如果属性key是一个NumbericIndex类型且其值大于(ta)的长度时,`Reflect.set`返回正确的结果(不兼容变更)。
70
71```js
72// 情况一:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,查找的key是一个大于(ta)的长度的下标
73function BehaviorChange1() {
74    // 以Int8Array为例创建一个TypedArray对象
75    const typedArray = new Int8Array(5);
76    typedArray[1] = 42;
77
78    // 创建一个Object对象,并将它的原型设置为TypedArray对象
79    const obj = Object.create(typedArray);
80    // 查找Object对象上是否有"6"这个属性的时候,遍历原型链查找
81    print(6 in obj); // 输出:false 符合规范,遍历原型链也找不到该属性
82}
83BehaviorChange1();
84
85// 情况二:当一个对象(o)的原型是TypedArray类型的对象(ta)时,通过`in`判断(o)上的是否存在某个属性,查找的key是一个NumbericIndex类型,且这个key在(ta)的原型对象上
86function BehaviorChange2() {
87    // 创建一个普通的Object对象,持有属性"6"
88    const obj1 = {};
89    obj1[6] = "b";
90
91    // 以Int8Array为例创建一个TypedArray对象
92    const typedArray = new Int8Array(5);
93    typedArray[1] = 42;
94    // 将typedArray的原型设置为第一步创建的obj1对象
95    typedArray.__proto__ = obj1;
96
97    // 创建一个Object对象,并将它的原型设置为TypedArray对象
98    const obj = Object.create(typedArray);
99    // 查找Object对象上是否有"6"这个属性的时候,遍历原型链查找
100    print("6" in obj); // 输出:false 符合规范,key是一个NumbericIndex类型,遍历原型链查找到typedArray后,不会再往之后的链上查找了
101}
102BehaviorChange2()
103
104// 情况三:通过`Reflect.set`向一个对象(o)中的某个属性key设置值value,本地调用的参数中的`receiver`是一个TypedArray类型的对象(ta),属性key是一个NumbericIndex类型且其值大于(ta)的长度
105function BehaviorChange3() {
106    // 第二个参数是propKey,第三个参数是value,第四个参数是receiver
107    print(Reflect.set({}, 100, 123, new Int32Array())); // 输出:false 100大于TypedArray对象的长度,添加属性会失败
108}
109BehaviorChange3();
110```
111
112**起始API Level**
113
114API 9
115
116**变更发生版本**
117
118从OpenHarmony 5.1.0.46 版本开始。
119
120**变更的接口/组件**
121
122使用ECMAScript内置函数`in`以及`Reflect.set`对Object类型对象且原型对象为TypedArray对象(包括Int8Array/Uint8Array/Int16Array/Uint16Array/Int32Array/Uint32Array/Uint8ClampedArray/Float32Array/Float64Array)进行属性访问相关的操作。
123
124**适配指导**
125
126使用上述三种情况访问或者设置TypedArray中的属性时注意返回值的变更。
127