您能否将javascript“存储”在数据库中,然后稍后执行?

nat*_*ate 2 javascript node.js

(请不要担心安全性或其他任何问题,因为它是内部应用程序)

基本上我想做的是在db中存储一个javascript函数:

 function x(name) {
   return name + 1;
 }
Run Code Online (Sandbox Code Playgroud)

然后在以后获取数据库行

(此处为伪代码)

 x = db.get('function').where('id').equals(1);

 console.log(x('bob'));
 //should print "bob +1 "
Run Code Online (Sandbox Code Playgroud)

所以这是我设想的方案:

基本上,我正在获取一个JSON对象,并且根据某些条件,我想对该json进行一些转换,然后输出新的转换后的json。出于“主”应用的考虑,我不想对转换逻辑进行硬编码,而是动态的(就动态而言,不同的开发人员将在运行时提供它)

因此数据库可能包含:

ID   |    javascript 
====================
1    |    (some js code)
2    |    (same func, different code)
Run Code Online (Sandbox Code Playgroud)

我想要做的是使用我选择的输入执行存储在数据库中的JS代码。

如果方便,函数名称将是标准的。即我们可以假定保存在数据库中的javascript都将遵循:

function transform(input) {
  /* below this line logic will change

* end diff logic/
 return output
}
Run Code Online (Sandbox Code Playgroud)

nnn*_*nnn 6

您可以使用eval()函数执行JS的任意字符串,这将返回所评估结果的结果。

因此,出于您的目的,要分配一个变量来保存字符串中的(求值)函数,可以这样做:

// retrieve string from DB somehow
var functionString = "(function whatever(name) { return name + 1; })";
var x = eval(functionString);
console.log(x("bob")); // logs "bob1"
Run Code Online (Sandbox Code Playgroud)

请注意,我将函数包装在字符串中的括号中,因为这使它成为函数表达式,然后可以将其分配给变量x

我不想对转换逻辑进行硬编码,而是动态的(从某种意义上说,动态的是不同的开发人员将在运行时提供它)

我认为另一种更好的方法是将所有转换函数放入一个单独的JavaScript模块中,然后require()根据标准Node.js模块加载系统。这样,转换逻辑就被保存在另一个文件中,该文件可以由其他开发人员根据需要单独维护,而不会影响数据库操作和eval()

// transforms.js
module.exports = {
  "1" : function plus1(name) { return name + 1; },
  "2" : function square(x) { return x * x; },
  "3" : function half(x) { return x / 2; }
  // etc.
};

// in main JS file
var transforms = require("./transforms.js");

var a = transforms["2"];
var b = transforms["3"];
console.log(a(b(20))); // 100
console.log(transforms["1"]("bob")); // "bob1"
Run Code Online (Sandbox Code Playgroud)

从上面可以看到,每个“动态”转换函数都已定义为对象的属性,其中属性名称是您要在数据库中使用的键。

StackOverflow代码片段似乎无法处理模块,但是如果您扩展以下代码片段,则可以看到与上述代码等效的代码:

// transforms.js
module.exports = {
  "1" : function plus1(name) { return name + 1; },
  "2" : function square(x) { return x * x; },
  "3" : function half(x) { return x / 2; }
  // etc.
};

// in main JS file
var transforms = require("./transforms.js");

var a = transforms["2"];
var b = transforms["3"];
console.log(a(b(20))); // 100
console.log(transforms["1"]("bob")); // "bob1"
Run Code Online (Sandbox Code Playgroud)

  • 虽然我喜欢第二种方法,但我唯一担心的是需求不会是动态的,而是在运行时加载的。 (2认同)