Skip to content

Instantly share code, notes, and snippets.

@tynrare
Last active February 12, 2020 02:29
Show Gist options
  • Save tynrare/998dcaa66b021661f07e74b572c7311d to your computer and use it in GitHub Desktop.
Save tynrare/998dcaa66b021661f07e74b572c7311d to your computer and use it in GitHub Desktop.
Safe JS CodeScriptExecutor
/**
* @file code_script_executor.js
* @author tynrare
* @version 1
* @module Core/Lib/CodeScriptExecutor
*/
/**
* Allows to execute js script from strings with scope bindings
*/
class CodeScriptExecutor {
/**
* Binds object into string function scope
*
* #chainable
*
* @param {object} object object to bind into scope
* @param {string} name name this object avaible in function scope
* @example
*
* const a = { foo: 1 }
* const b = { bar: 2 }
* executor.bind(a, 'a').bind(b, 'b')
* const result = executor.execute('a.foo+b.bar'); //3
*
* @returns {CodeScriptExecutor} this
*/
bind(object, name) {
this.bindedObjects[name] = object;
this.bindedObjectsStringCache += `var ${name} = args[${this.bindedObjectsCountCache++}];`;
return this;
}
/**
* Executes code from string
* Based on mdn guide - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Never_use_eval!
*
* @param {string} code some js code
* @example
*
* //global scope example
* const a = 10;
* const b = 10;
* const result = executor.execute('a+b'); //20
*
* @returns {*} any code result
*/
execute(code) {
const func = `"use strict";return (function(args){ ${this.bindedObjectsStringCache} return (${code}); })`;
/* eslint-disable no-new-func */
return new Function(func)()(Object.values(this.bindedObjects));
/* eslint-enable no-new-func */
}
/**
* {Object} all scopes added by bind()
*
* @private
*/
bindedObjects = {};
/**
* {string} inner string code cached variables
*
* @private
*/
bindedObjectsStringCache = '';
/**
* {number} objects counter cache
*
* @private
*/
bindedObjectsCountCache = 0;
}
export default CodeScriptExecutor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment