正如反复提到的,使用Function构造函数被认为是不好的做法(另见ECMAScript语言规范,第 5 版,第15.3.2.1节):
new Function ([arg1[, arg2[, … argN]],] functionBody)
Run Code Online (Sandbox Code Playgroud)
(其中所有参数都是包含参数名称的字符串,最后一个(或唯一)字符串包含函数体).
要概括,它被认为是缓慢的,因为通过解释歌剧院团队:
每次
Function在表示源代码的字符串上调用构造函数时,脚本引擎必须启动将源代码转换为可执行代码的机制.这通常对性能来说很昂贵 - 例如,比简单的函数调用要贵一百倍.(Mark'Tarquin'Wilton-Jones)
虽然它并没有那么糟糕,但根据这篇关于MDC的帖子(我没有使用当前版本的Firefox自己测试).
克罗克福德补充说
引用该语言的惯例使得将函数体正确表达为字符串变得非常困难.在字符串形式中,无法进行早期错误检查.[...]它浪费了内存,因为每个函数都需要自己独立的实现.
另一个不同之处在于
由Function构造函数定义的函数不会继承除全局范围(所有函数都继承)之外的任何范围.(MDC)
除此之外,在创建new Function使用动态内容时,您必须注意避免注入恶意代码.
也就是说,TJ Crowder在回答中说
除了一些高级边缘情况之外,这里几乎从不需要类似的新函数(...).
所以,现在我想知道:这些"先进边缘案例"是什么?Function构造函数是否合法使用?
我无法new Function在Web Worker中工作.我有一个HTML页面,它产生了一个Web Worker.此Web Worker通过执行代码new Function(str).我正在尝试在打包的Chrome应用中使用此功能,这需要使用类似eval代码的页面在清单中明确列为沙盒页面.
现在,有两种选择:
new Function,但我无法生成Web Worker,因为我无法发出任何请求(沙盒页面具有唯一的来源).new Worker(...)抛出一个SECURITY_ERR.
new Function 适用于沙箱new Worker 由于独特的起源而在沙盒中失败new Function因为它不是沙箱.new Function(...)抛出一个EvalError关于它的使用抱怨.
new Function未能在非沙箱由于是eval样new Worker 适用于非沙箱我的CSP如下:
sandbox allow-scripts script-src 'self' 'unsafe-eval'; object-src 'self'
Run Code Online (Sandbox Code Playgroud)
如何new Function在Web Worker中工作?
javascript google-chrome web-worker function-constructor content-security-policy
想象一下以下代码:
$.get( "ajax/getColorData.php", function( data ) {
this.colorData = data;
});
Run Code Online (Sandbox Code Playgroud)
现在设想'数据'的价值是:
this.colorData = [
{
colorName: 'Red',
colorIsInRainbow:true
},
{
colorName: 'Orange',
colorIsInRainbow: true
},
{
colorName: 'Magenta',
colorIsInRainbow: false
}
];
Run Code Online (Sandbox Code Playgroud)
问题1
现在,在我下载数据之后,假设我想为数组中的每个条目添加一个方法"colorStartsWithR".我"想"而不是在数组的每个成员上定义它,我可以在原型上以某种方式定义这个方法.但是,我不确定我能做到这一点,因为这些对象不是由我创建的,而是由$ .get返回的,所以我不清楚我是否正在思考正确的方向.
问题2
更进一步,如果我想为数组的每个成员添加一个属性,具体如下:
{
colorName: 'Magenta',
colorIsInRainbow: false,
userClickedThisColor:ko.observable()
}
Run Code Online (Sandbox Code Playgroud)
这样,我可以绑定(通过knockoutjs)列表并包含一个复选框.在这种情况下,我质疑原型是否会派上用场,因为每个成员都应该获得自己的ko.observable属性.一个快速的本能是做一些事情:
for (var i=0;i<this.colorData.length;i++)
{
this.colorData[i].userClickedThisColor=ko.observable()
}
Run Code Online (Sandbox Code Playgroud)
并且工作正常,但想象一下,有多种方法可以检索颜色列表,或者用户可以创建新的颜色实例,并且我在上面做的自定义更复杂.我现在需要复制上面的"附加"逻辑.有更聪明的方法吗?
我把大部分时间花在强类型语言上,有时这些事情对我来说并不那么明显.谢谢你的任何建议......
-ben
void(document.body.innerText += 'hi')
eval(document.body.innerText +='\nbye')
Function(document.body.innerText += '\n!!!')
void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())();
eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())();
Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())();Run Code Online (Sandbox Code Playgroud)
在这些不同的语句中执行代码的处理模型是什么?
void(alert('hi'))
undefined
eval(alert('hi'))
undefined
Function(alert('hi'))
function anonymous() {
undefined
}
eval(Function(function foo(){return true}).toString())();
TypeError: undefined is not a function
void(Function(function foo(){return true}).toString())();
TypeError: string is not a function
Function(Function(function foo(){return true}).toString())();
undefined
Run Code Online (Sandbox Code Playgroud) function define(prop, value) {
Object.defineProperty( /* context of caller */ , prop, {value: value});
}
function F() {
define('x', 42);
}
var f = new F();
Run Code Online (Sandbox Code Playgroud)
有没有办法获取调用函数的上下文(在上面的代码中内联注释)?
如果我绑定到这个(将注释替换为this)并在F构造函数中声明,它工作正常var def = define.bind(this);
1.var f = new Function("a", "b", "return a+b")
2.var f2 = Function("a", "b", "return a+b")
f而f2这两个是一个匿名函数.f(1,2)并且f2(1,2)都返回3.那么两者之间是否有任何实际的内部差异?Function内部是否返回一个函数对象?与使用Functionas构造函数的区别new Function(...)?
这些功能的操作方式有什么不同吗?第一个更典型的是我在考虑构造函数时所想到的。
示例1:使用它来命名和设置属性。然后使用new创建一个新的Book对象。
function Book(name, numPages) {
this.name = name;
this.numPages = numPages;
}
var myBook = new Book('A Good Book', '500 pages');
Run Code Online (Sandbox Code Playgroud)
示例 2:使用new返回一个对象并仅调用函数本身。
function Movie(name, numMinutes) {
return { name:name, numMinutes:numMinutes };
}
var best = new Movie('Forrest Gump', '150');
var other = Movie('Gladiator', '180');
Run Code Online (Sandbox Code Playgroud)
我想我想弄清楚的是它们创建对象的方式是否不同?如果是这样,一个比另一个更好吗?是否有不同的情况下,其中一种会比另一种表现得更好?
javascript constructor javascript-objects function-constructor
javascript ×7
arrays ×1
constructor ×1
ecmascript-5 ×1
eval ×1
function ×1
new-operator ×1
this ×1
void ×1
web-worker ×1