A new look at JavaScript injection

    I recently faced the following task - there is a JavaScript actions object with a bunch of methods, in each of which the following variables must be defined:

    var persik = this,     
          actions = persik.actions,      
          next = (persik.dom.possibly MORE THAN.This name is of this Method.next)? 
              persik.dom.possibly MORE THAT.name of ThisMethod.next: function () {return false}; 
    


    But I really didn’t want to define them, because, firstly, the code will be noticeably heavier, and secondly, the actions object was created for future users of my Persik framework, and it is assumed that everyone can not only use ready-made actions, but also define their own. You can, of course, write in the documentation “guys, please insert these lines at the beginning of each method you create”, or not create any variables at all and write this instead of persik (although there may be problems with this), write this instead of actions .actions, and instead of calling next (), blurt out something like:
    if (this.dom.possiblyMoreWhatThis.name of ThisMethod.next) this.dom.possibly MoreWhat this.name of ThisMethod.next ();
    But all this is terribly neither beautiful nor right, and I decided to go the other way. The idea is simple - when initializing the framework, go through all the methods of the actions object, use toString () to get each method as a string, brazenly insert the necessary lines of variable definition there, make the function from the string again using eval () and replace the existing method with the modified one. I will not provide the source code for searching for methods inside actions in my framework so as not to bother the public, but the modification of the methods looks something like this:

    _rewriteFunc: function (func, funcName, variablesStr) {     
          var funcArr = func.toString (). split ('{');     
          variablesStr = variablesStr.replace (/ \ [funcName \] / g, funcName);     
          funcArr [1] = variablesStr + funcArr [1];               
          var resultFunc = funcArr.join ('{');     
          eval ('var a =' + resultFunc);         
          return a; 
    },
    


    Here func is an actually modifiable method, the name of this method is passed to funcName, and taking into account all parents, i.e. then this.dom.possibly, MORE THAT. name of this Method, and variablesStr contains a string with the variables that we define. In my case it is' var persik = this; var actions = persik.actions; var next = ([funcName] .next)? [funcName] .next: function () {return false}; '. The function described above replaces everything '[funcName]' in variablesStr with funcName, inserts variablesStr into resultFunc after the first character '{', collects the function from the string again and returns it back. The actions object, over which all of the above perversions are performed, can be viewed here: nikitaeremin.com/js/action.js

    This technique has several disadvantages:
    - variables persik, actions and next are created in all methods of the actions object, although in some methods they may remain unclaimed;
    - the source code of JavaScript changes, and if errors occur during the execution period, FireBug will not swear at all the lines that actually caused the error, although the cause of the error is correct;
    - the rest of the minuses will be said to me by the general public :)

    I do not think that the trick described above is applicable to a wide range of tasks, this article is more likely for general development, but if someone wants to share ideas about other areas of application of such injections, write to the soap: nikitaeremin [at] gmail.com

    Also popular now: