什么是正确的“;串行化”;javascript中的函数以供以后使用
What is the correct way to "serialize" functions in javascript for later use
我有一个对象的"库",我想从数据库中动态加载这些对象。每个对象都有自己的特殊函数,根据对象类型在特定时间调用这些函数。理想情况下,我希望能够做到这一点,尽管有人指出这不起作用:
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
字符串"myObj"
经常在我的程序中传递,但我一次只需要访问对象的某些值,在某些情况下,需要运行特定的函数。问题是,我看到的是成百上千个潜在的对象,它们可能具有不同的功能。
存储这样调用的函数的"正确"方式是什么。我知道调用eval在执行过程中可能非常不安全,从而导致xss攻击等等。我真的想避免大量的switch语句或额外函数的过度加载。我也希望解决方案尽可能简洁。
这不可能是第一次出现这种情况
谢谢你的帮助。
将函数加载为字符串后,只需使用eval即可重新创建函数。因此,如果您从JSON反序列化对象myObj
,并且您有一个属性:
myObj = {
....
function: "function() { ... }"
}
你可以很容易地把它变成一个真正的功能:
eval("myObj.func = " + myObj.func);
http://jsfiddle.net/kceTr/
哦——我不确定这是编辑还是我以前错过了——但重新评估。
Eval是一种工具。您希望将函数存储在数据库中。如果你必须"评估"才能将其转化为代码,或者有其他神奇的方法:如果有人可以更改你数据库中的数据,那么他们可以更改函数,这真的没有多大区别。
如果你需要存储一个函数,那么eval就是你的工具。它本质上并不"坏",它很坏,因为它很容易被滥用。你用得好与否取决于你自己。
请记住,在客户端上运行的任何内容仍然只是在客户端上执行。恶意的人不能用eval做任何事情,他们不能更容易地用Chrome调试器做任何事情。任何人都可以在客户端上运行他们想要的任何代码,这取决于你的服务器来决定如何处理它接收到的内容。客户一开始就没有安全可言。。。
更改对象的原型是我的一半想法。
你的图书馆就像一样
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
您有一个对象(让我们称之为theObj
),您知道它是myObj
(由于字符串可能是?属性?)
theObj.__proto__ = library["myObj"];
这样你就可以执行
theObj.function(...);
jsfiddle示例(这是粗糙的!)。此外,要小心proto,它已被弃用(1)(2)
至于序列化函数,你能使用一个脚本标签来获取它们吗?这个标签指向服务器端的某个东西,从数据库中抓取它们并返回js?在渲染页面时(在脚本块中)只将它们内联吗?或者,如果所有其他操作都失败了,那么eval应该可以工作,只要您知道存储在数据库中的函数是干净和安全的。
没有正确的方法来做到这一点,因为这通常不是一个好主意。
然而,如果你想以任何方式做到这一点,你可以简单地用.toJSON
方法扩展Function的原型。
Function.prototype.toJSON = function(){ return this.toString(); }
然后您可以简单地使用JSON.stringify,函数将被序列化为字符串。
在大多数情况下,这通常不是一个好主意。很少有情况下你想这样做,即使这样,也可能有更好的方法。
更好的方法可能是在"休眠"对象时序列化对象的属性,并通过使用定义的适当方法将其属性重新附加到对象的新实例来"唤醒"对象。
您使用它所做的一切都很好。然而,如果我是你,为了可读性和简洁性,我宁愿在外部创建函数,并将其分配给你的对象键。
这里不需要eval。相反,只要你想访问存储的功能-,就可以这样做
library.myObj.function()
- 你尽你最大的努力参数化你的函数,这样你尽可能少的类型
- 将它们存储在服务器上的各个JS文件中,然后按名称动态加载所需的文件
- 在JSON中,只存储包含所需函数的文件名。当然,您将缓存已经加载的文件,以便在服务器上轻松操作
只有我的两美分。
你只能用require
调用来串行化整个文件。如果你这样做,你可以创建一个模块,导出和module.exports,用一个围绕它的函数来评估文件,并从中获取module.export。
它并不完全安全,但为此,你需要使用VM2和价值审查(我一直在研究)之类的东西,以避免他们调用eval()并拥有你的机器或整个网络。
- 从函数JavaScript返回不可变数组/对象
- 将对象传递给函数.JavaScript
- 如何定义const函数javascript(语法糖)
- 新的日期函数javascript
- TypeError:this.getAttribute不是一个函数-javascript
- 从函数javascript发送变量
- 扩展自容器函数Javascript
- 从内部函数javascript内部分配外部函数的对象
- 使用函数JavaScript中的函数
- 在这里使用回调函数(JavaScript)有什么好处吗
- 来自函数 Javascript 的 NaN 返回值 ||函数执行顺序
- 将“e”传递给一个新函数 - javascript
- 调用函数中的一个函数——Javascript
- 传递的变量不适用于我的函数-Javascript
- 如何将类方法设置为等于多个函数?-Javascript
- 显示php中的函数javascript
- 如何使用php代码创建函数Javascript弹出框
- 未调用的外部函数-javascript
- 如何在类中运行函数.Javascript
- 关闭mouseover上的一个函数——Javascript,jQuery