简体   繁体   中英

Using splice to empty an array with Chromium

I am translating a program from c++ to typescript, and I face a strange behaviour trying to empty an array using the splice technique ( How do I empty an array in JavaScript? ) to empty an array.

Here is an excerpt of my code in typescript

 "use strict" class UniformGridGeometry<ItemT> extends Array<ItemT> { itemType: { new (): ItemT; } constructor(itemType: { new (): ItemT; }) { // constructor(itemType: { new (): ItemT; }, uGeomTemplate: UniformGridGeometry<any>) // any : Vorton, Particle, Vec*, Mat*, ... // constructor(itemType: { new (): ItemT; }, uNumElements: number, vMin: Vec3, vMax: Vec3, bPowerOf2: boolean) // constructor(itemType: { new (): ItemT; }, arg?: any, vMin?: Vec3, vMax?: Vec3, bPowerOf2?: boolean) { super(); // Array this.itemType = itemType; // (...) } } class UniformGrid<ItemT> extends UniformGridGeometry<ItemT> { constructor(itemType: { new (): ItemT; }) { // constructor(itemType: { new (): ItemT; }, uGeomTemplate: UniformGridGeometry<any>) // any : Vorton, Particle, Vec*, Mat*, ... // constructor(itemType: { new (): ItemT; }, uNumElements: number, vMin: Vec3, vMax: Vec3, bPowerOf2: boolean) // constructor(itemType: { new (): ItemT; }, arg?: any, vMin?: Vec3, vMax?: Vec3, bPowerOf2?: boolean) { super(itemType); // (...) } } class NestedGrid<ItemT> extends Array<UniformGrid<ItemT>> { constructor(src?: UniformGrid<ItemT>) { super(); if (src) { this.Init(src); } } Init(src: UniformGrid<ItemT>) { this.splice(0, this.length) // mUniformGrids.Clear() ; console.assert(typeof src === 'object', typeof src); // let numUniformGrids = this.PrecomputeNumUniformGrids( src ) ; // this.mUniformGrids.Reserve( numUniformGrids ) ; // Preallocate number of UniformGrids to avoid reallocation during PushBack. let uniformGrid = new UniformGrid<ItemT>(src.itemType); // uniformGrid.Decimate( src , 1 ) ; // uniformGrid.Init() ; this.push(uniformGrid); // (...) } } function doTests() { console.info("Test > NestedGrid ; UniformGrid"); let mInfluenceTree: NestedGrid<any> = new NestedGrid<any>(); // Influence tree let ugSkeleton = new UniformGrid<any>(null); mInfluenceTree.Init(ugSkeleton); console.log(mInfluenceTree); mInfluenceTree.Init(ugSkeleton); console.log(mInfluenceTree); } doTests(); 

that generates (ES6 target) the following Javascript :

 "use strict"; class UniformGridGeometry extends Array { constructor(itemType) { super(); this.itemType = itemType; } } class UniformGrid extends UniformGridGeometry { constructor(itemType) { super(itemType); } } class NestedGrid extends Array { constructor(src) { super(); if (src) { this.Init(src); } } Init(src) { this.splice(0, this.length); console.assert(typeof src === 'object', typeof src); let uniformGrid = new UniformGrid(src.itemType); this.push(uniformGrid); } } function doTests() { console.info("Test > NestedGrid ; UniformGrid"); let mInfluenceTree = new NestedGrid(); let ugSkeleton = new UniformGrid(null); mInfluenceTree.Init(ugSkeleton); console.log(mInfluenceTree); mInfluenceTree.Init(ugSkeleton); console.log(mInfluenceTree); } doTests(); 

The same code, on firefox or as code snippet works well, but on chromium the assertion fails, the argument 'src' becomes a number (the size of the array in fact) what am I doing wrong ? (the two Init calls simulates the processing in the WebGL loop)

chromium splice failing

Thanks.

It looks like splice , which creates a new array to return the deleted elements, reuses the class of the element it's called on, hence calling your custom constructor with the desired size.

Here you can fix the problem by using the other way to empty an array: setting its size to 0 . Replace

this.splice(0, this.length);

with

this.length = 0;

Another solution might have been to respect the contract of the class you extends as Array's constructor has a different behavior than the one you're implementing in the subclass.

Note that you're in a grey area, regarding specifications. It's probably wiser to avoid extending basic classes like Array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM