2016-07-06 3 views
3

Я переводил программу из C++ в машинопись, и я сталкиваюсь с странным поведением, пытающимся опорожнить массив, используя метод сплайсинга (How do I empty an array in JavaScript?), чтобы освободить массив.Использование сплайсинга для пустого массива с Chromium

Вот выдержка из моего кода в машинописи

"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();

, который генерирует (ES6 цель) следующие 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();

Тот же код, на firefox или как фрагмент кода работает хорошо, но по хром утверждение терпит неудачу, аргумент 'src' становится числом (размером массива на самом деле), что я делаю неправильно? (два вызова инициализации моделирует обработку в контуре WebGL)

chromium splice failing

спасибо.

ответ

1

Похоже, что splice, который создает новый массив для возврата удаленных элементов, повторно использует класс вызываемого им элемента, поэтому вызывает ваш пользовательский конструктор с требуемым размером.

Здесь вы можете исправить эту проблему, используя другой способ для удаления массива: его размер равен 0. Заменить

this.splice(0, this.length); 

с

this.length = 0; 

Другим решением может быть уважать контракт класса вы выступаете в качестве конструктора массива имеют различное поведение, чем тот, который вы реализующие в подклассе.

Обратите внимание, что вы находитесь в серой области, касающейся спецификаций. Вероятно, разумнее избегать распространения базовых классов, таких как Array.

+0

Благодарим за объяснение, я не заметил этого конфликта с конструктором arrayLength для Array! Исправление работает хорошо с хромом, но я буду следовать вашему совету, поэтому мне не придется расширять класс Array вообще, я действительно изменил бы дизайн, чтобы создать новый массив, вместо того, чтобы освобождать его из расширенного класса , –

Смежные вопросы