If you want to block certain variables when converting a function to a string, you need to pass these variables along the string function.
It can be implemented as follows (written with type - typescript)
const prepareForEval = (fn: Function, variablesToLock: { [varName: string]: any }): string => { const stringifiedVariables = Object.keys(variablesToLock) .map(varName => `var ${varName}=${JSON.stringify(variablesToLock[varName])};`); return stringifiedVariables.join("") + fn.toString(); }
Then use it like this:
const stringifiedFunction = prepareForEval(someFunction, { x: x, y: y })
Any eval will declare string variables and funtion in the place where it was executed. This can be a problem, you can redefine a variable to a new unknown value, you must know the name of the gated function in order to be able to call it, or it can cause an error if you re-declare an already declared const variable.
To overcome this problem, you must implement a gated function as a directly executed anonymous function with its own scope, e.g.
const prepareForEval = (fn: Function, variablesToLock: { [varName: string]: any }): string => { const stringifiedVariables = Object.keys(variablesToLock) .map(varName => `var ${varName}=${JSON.stringify(variablesToLock[varName])};`); return ` var ${fn.name} = (function() { ${stringifiedVariables.join("")} return ${fn.toString()}; )(); `; }
this modification will declare the function and variables in a separate scope, and then assign this function to the constant fn.name . The variables will not change the scope where you are eval , it will simply declare a new variable fn.name , and this new variable will be set to a deserialized function.
Vaclav
source share