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