These are strings, and not functions. To run them you need to evaluate them using eval()
(or Function and then run them). Each string is an expression, and not an actual function. Running the expression will create global variables (container1
, container2
, and container3
).
You've probably heard that eval()
is evil. Using eval()
is a security risk, and hurts performance, and Function is only slightly less so (read more here):
eval() is a dangerous function, which executes the code it's passed
with the privileges of the caller. If you run eval() with a string
that could be affected by a malicious party, you may end up running
malicious code on the user's machine with the permissions of your
webpage / extension. More importantly, a third-party code can see the
scope in which eval() was invoked, which can lead to possible attacks
in ways to which the similar Function is not susceptible.
Function's advantage is that it runs in the global scope, and can't access variables in the scope it was called in. However, Function still allows running arbitrary code.
Eval example:
const PIXI = {
Container: function () {
this.example = 'Container';
}
};
const newPIXI = ["container1 = new PIXI.Container();","container2 = new PIXI.Container();","container3 = new PIXI.Container();"]
newPIXI.forEach(x => eval(x))
console.log({ container1, container2, container3 });
Function example:
const PIXI = {
Container: function () {
this.example = 'Container';
}
};
const newPIXI = ["container1 = new PIXI.Container();","container2 = new PIXI.Container();","container3 = new PIXI.Container();"]
newPIXI.forEach(x => Function(x)())
console.log({ container1, container2, container3 });
It's better to pass data that tells the browser what you want to do (a command), and not how to do it. Then in the code you can decide how to interpret the command. For example:
const PIXI = {
Container: function () {
this.example = 'Container';
}
};
const newPIXI = [{ type: 'PIXIContainer', name: 'container1' }, { type: 'PIXIContainer', name: 'container2' }, { type: 'PIXIContainer', name: 'container3' }]
const result = {};
newPIXI.forEach(({ type, name }) => {
switch(type) {
case 'PIXIContainer':
result[name] = new PIXI.Container();
break;
default:
throw new Error(`Type ${type} not found`);
}
})
console.log(result);