2016-09-19 2 views
0

вот мой случай использования:Как установить ссылочную переменную в значение null?

на Phaser.io, когда пользователь нажал на кнопку, я установил Phaser.sprite к локальной let newSquare переменной, и я .push() его на Squares массив Phaser.sprite.

Позже я вызываю функцию destroy на этой переменной newSquare, а затем устанавливаю ее в нуль. В то время как спрайт хорошо удаляется с экрана после .destroy(), я все еще могу получить доступ к нему из моего Squares массива ...

Я подумал, что, будучи объектом, если я установить переменную newSquare нулевое значение, было бы установить для null для всех других ссылок тоже, не так ли?

Итак, почему мой ref в массиве Squares не установлен в null?

Выдержки:

eventFunction (e, i) { 
     let newSquare = Game.add.sprite(Lines.attack.a, 0, 'square'); 

     // Some other methods call here 
     Squares[ e.target.dataset.line ].push(newSquare); 

     setTimeout(() => { 
     if (newSquare) { 
      newSquare.destroy(); 
      newSquare = null; 
      console.log(Squares); // will print an array with an iteration corresponding to newSquare object, when I want it to be set to null, in order to clean the array with a _.pull() 
     } 
     }, (2 * 1000)); 

} 

Что я здесь отсутствует? Спасибо вам.

+2

не особо. вы можете иметь несколько ссылок на одну и ту же «вещь». установка одной из этих ссылок на нуль не приводит к недействительности других ссылок. Но вызов '.destroy()' WILL аннулирует их. вы явно уничтожили объект, что означает, что все остальное, используя эти другие ссылки, теперь будет пытаться использовать свой «указатель» на объект, который был уничтожен. Это будет похоже на то, что в вашем доме есть 3 примечания, говорящие «носки в ящике под кроватью». Если вы сжечь одну из постеров, у вас все еще будут носки в ящике. но если вы сожжете ящик, эти заметки будут ВСЕ ЕЩЕ говорить, что там есть носки. –

+0

@MarcB Я не знаю, что именно '.destroy' делает в Phaser, но я думаю, что лучшей аналогией было бы то, что он закрывает и блокирует ящик для носка.Так что он все еще там, все признаки указывают на него, и у него, вероятно, все еще есть носки, но вы не можете добраться до них. – vlaz

ответ

2

Вы только сбрасываете ссылку на объект, который был изначально создан. Объект все еще существует в памяти и имеет ссылку на него через доступ к массиву. Это означает, что он не получит сбор мусора. Вам нужно будет аннулировать его в массиве ...

Это упрощенная версия вашей проблемы.

let x = {a: 1, b: 2, c: 3}; 
let y = x; 

x = null; 
console.log(y); 
// => {a: 1, b: 2, c: 3} 

Я бы сказал, сохранить ссылку на элемент в памяти и использовать эту ссылку, чтобы найти индекс объекта в массиве, push Эда. НАПРИМЕР,

array.find(el => el === reference) 

... где reference это идентификатор, который вы ранее присваивание null.

Способ обнуления элемента и поддержания его текущей позиции в массиве состоит в том, чтобы сопоставить вашу коллекцию с помощью reference, чтобы найти ваш товар. НАПРИМЕР,

array = array.map(el => el === reference ? null : el) 

Если вы ищете мутационной способ изменить элемент в месте, используйте forEach(..). НАПРИМЕР,

array.forEach((x, i, arr) => { 
    if (x === reference) { 
    arr[i] = null; 
    } 
    return; 
}); 

forEach вызова будет посещать каждый элемент в массиве, так что если вы хотите короткое замыкание итерации, попробуйте использовать indexOf цикл.

const i = array.indexOf(reference); 
array[i] = null; 
+1

'array.map (...)', который не будет изменять массив на месте. – vlaz

+0

Да, ты прав. Думаю, я использовал «на месте» слишком либерально. Я имел в виду его текущее положение в массиве. Я изменю его на мутативный 'forEach (..)' – wpcarro

+0

Итак, моя переменная 'newSquare' относится к зоне памяти, где начинается мой объект, хорошо. Но как я могу отключить то, что находится в этом адресе памяти через 'newSquare' ?? Если я могу получить доступ к объекту и вызвать его метод, я должен уметь иметь способ сказать «положить кучу 0 бит, где мои новые точки поиска», нет? –