2 ms·
Exactly. This is my problem with the `new` syntax. There are still other problems (in my opinion) with the concept of constructor functions. It basically boi
by strager 15y ago
Exactly. This is my problem with the `new` syntax.
There are still other problems (in my opinion) with the concept of constructor functions. It basically boils down to mixing data (prototype) and code (constructor funciton).
Side-effects in a constructor are a big no-no. However, if you want side-effects, you're forced to write your code in a different style.
As a (really bad) example, you have an Enemy "class" which must know about enemies adjacent to itself at creation time.
Without side-effects (using `new`):
var enemy = new Enemy(enemyList);
enemyList.push(enemy);
// Now enemy is inside of enemyList,
// but it's not enforced. I find this
// method prone to mistakes.
With side-effects (using `new`):
var enemy = new Enemy(enemyList);
// Now enemy is inside of enemyList;
// I wouldn't expect that postcondition!
And without constructors, but with side-effects:
var enemy = enemyList.createEnemy();
// or
var enemy = createEnemy(enemyList);
// Now enemy is inside of emptyList
The problem here is that an enemy must be part of a list. The classical OO solution is to use constructor parameters. Ideally, I'd just have a function to deal with creation and adding it to the list (like `createEnemy`).
In ES5, `enemyList.createEnemy` could be written like this:
var enemy = Object.create(Enemy.prototype, {
enemyList: { value: this } // Ugh!
});
this.push(enemy);
Enemy.call(enemy); // Necessary evil if you use standard JS "classes"
return enemy;
I'd much prefer something like:
var enemy = enemyProto { enemyList: this }; // Basically binds the object literal with the enemyProto prototype, returning the modified object.
this.push(enemy);
// enemy ctor logic here; e.g. Enemy.call(enemy) as above
return enemy;