Is there a way to call a function by string parameter? Let's say I have an array of object names: Code (javascript): loaded_plugins = new Array('Tournament', 'Hangman', 'Battlezone', 'Trivia'); The plugin names are the object names. Tournament.beforeChatMessage is a function and it works if I call it manually. But when I do something like this: Code (javascript): this.executeEvents = function(event_name) { for (var i in this.loaded_plugins) { if (typeof loaded_plugins[i][event_name]() == 'function') { eval(loaded_plugins[i][event_name]()); } } } nothing is executed as loaded_plugins[event_name] is always undefined. As you can call properties and functions of an object in javascript by index Tournament['beforeChatMessage'] should be called. So any ideas?
BLARGH. DONT DO THIS. I'm not even going to tell you what you did wrong.. because it'd still be wrong! You don't need to be compiling code on the fly, your code should not include a jit compiler! It's extremely error prone, causes bugs, and suffering. Here it might not cause any issues, but it's a very bad habit and results in 75% + of script security vulnerabilities. Instead do something like this: Code (javascript): this.plugins = new Object; this.plugins["tournament"] = sys.exec("tournament.js"); //if you don't have sys.exec you can use sys.import or eval(sys.getFileContent("tournament.js") this.nilfunc = function () {}; for (var x in this.plugins) (this.plugins[x][event_name] || this.nilfunc)();
You should access them as variables. Every global variable is in the 'this' keyword (global scope), assuming there is no other scope taking priority. For example, like so: Code (javascript): // You should put this before the ({ }) block. var loadedPlugins = ["Tournament", "Hangman", "etc"]; var global = this; // This makes it possible to access the global scope everywhere (assuming this is run in the global scope) function executeEvents(eventName) { var len = loadedPlugins.length, plugin, i; for (i = 0; i < len; i += 1) { plugin = global[loadedPlugins[i]]; if (plugin[eventName]) { plugin[eventName](); } } }
No, the actual error is that's he's trying to 1. call a property of a string and 2. eval the result? What he was trying to do was some kind of silly JS code generation. But this is a bad way to code anyway and I strongly don't recommend it. I recommend NEVER using the global scope. It's a bad habit and using it like that errors in JavaScript strict mode (not to be confused with sys.enableStrict, which is changes the way some sys functions work) Try using another object.
That's your personal choice and opinion. Putting everything into native and pseudo native (sys, script) objects isn't exactly a good habit either. QtScript does not have strict mode, and probably never will. It's also completely optional: »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» (01:48:05) ~Client~: You evaluated the following code: (function () { 'use strict'; var a = 013; return a;}()); »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» (01:48:06) ~Client~: 11 (01:48:06) ~Client~: Code took 0 milliseconds / 0 seconds to run. Strict mode isn't the best thing either, and tends to break things in certain environments. Again, that's up to personal preference. If someone wants to use the global scope, so be it. It's there for a reason.
Putting everything into script is actually a good habit. If it's part of your script, shouldn't it be part of the script object? Modifying sys is always a bad idea. It's a preference until it breaks things or causes memory leaks. Then it's a preference that breaks things and causes memory leaks. I'm not going to demand anyone code like that, but I strongly recommend it.
Oh right, Garma, sorry. Try this: Code (javascript): this.executeEvents = function(event_name) { for (var i in this.loaded_plugins) { if (typeof this.loaded_plugins[i][event_name] == 'function') { this.loaded_plugins[i][event_name](); } } } You don't need the eval. If you have the name for the function, you can just do containingobject[nameofthefunction](function arguments). I'm not sure about the typeof call, but that's it.
The problem is he's got the /names/ of global properties instead of a property of an object. So you'd probably need eval to read them. aka, he has to do Code (text): eval (loadedplugins[i] + "[eventname]()"); BUT that's bad scripting! Instead he should make loaded plugins an array of the actual plugin objects (instead of their names) then you wont need eval or global object hacks.