可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
If I have an array of objects is there any way possible for the item to splice itself out of the array that contains it?
For example: If a bad guy dies he will splice himself out of the array of active enemies.
I probably sound crazy but that ability would simplify my code dramatically, so I hope for something cool =)
回答1:
The way you would do it is as follows:
var game_state = { active_enemies: [] }; function Enemy() { // Various enemy-specific things go here } Enemy.prototype.remove = function() { // NOTE: indexOf is not supported in all browsers (IE < 8 most importantly) // You will probably either want to use a shim like es5-shim.js // or a utility belt like Underscore.js var i = game_state.active_enemies.indexOf(this); game_state.active_enemies.splice(i, 1); }
See:
Notta bene: There are a couple of issues here with this manner of handling game state. Make sure you are consistent (i.e. don't have enemies remove themselves from the list of active enemies, but heroes remove enemies from the map). It will also make things more difficult to comprehend as the code gets more complex (your Enemy not only is an in-game enemy, but also a map state manager, but it's probably not the only map state manager. When you want to make changes to how you manage map state, you want to make sure that code is structured in such a way that you only need to change it in one place [preferably]).
回答2:
Assuming the bad guy knows what list he's in, why not?
BadGuy.prototype.die = function() { activeEnemies.splice(activeEnemies.indexOf(this), 1); }
By the way, for older browsers to use indexOf
on Arrays, you'll need to add it manually.
回答3:
You kind of want to avoid circular references
回答4:
I would suggest creating an object/class that represents the active enemies list. Create methods on that instance for adding/removing a given item from the list - abstracting the inner workings of the data structure from the outside world. If the active enemies list is global (e.g. there's only one of them), then you can just reference it directly to call the remove function when you die. If it's not global, then you'll have to give each item a reference to the list so it can call the function to remove itself.
回答5:
You can also use an object and instead of splice, delete the enemy:
var activeEnemies = {}; function Enemy() { this.id = Enemy.getId(); // function to return unique id activeEnemies[this.id] = this; // .... } Enemy.getId = (function() { var count = 0; return function() { return 'enemyNumber' + count++; } }()); Enemy.prototype.exterminate = function() { // do tidy up delete activeEnemies[this.id]; } Enemy.prototype.showId = function() { console.log(this.id); } Enemy.prototype.showEnemies = function() { var enemyList = []; for (var enemy in activeEnemies) { if (activeEnemies.hasOwnProperty(enemy)) { enemyList.push(enemy); } } return enemyList.join('\n'); } var e0 = new Enemy(); var e1 = new Enemy(); console.log( Enemy.prototype.showEnemies() ); // enemyNumber0 // enemyNumber1 e0.exterminate(); console.log( Enemy.prototype.showEnemies() ); // enemyNumber1