如何强制 'function' 成为一个表达式,而不是一个语句?
How to force 'function' to be an expression, not a statement?
虽然这段代码没问题:
var x = function() { };
此代码不是:
function() { };
上面的示例创建了一个匿名函数并将其分配给 x
。下面的例子是一个语句,其中需要函数名,所以是语法错误。
现在,定义一个匿名函数而不在任何地方分配它似乎毫无意义,但这里有一个面对这种行为的例子:
var x = eval('function() { }');
它的行为应该与第一个示例一样,但存在语法错误。
在我正在开发的应用程序的深处,我们遇到了这个问题。我希望 function() { }
成为一个表达式。
一个简短的解释为什么这是一个原生 OSX 应用调用 javascript 进入 WebView
。我们有一个 evaluateJavascript
函数,原生层可以使用它来调用任意 javascript。 evaluateJavascript
用 try/catch
包装给定代码以进行错误处理,因为这是获取详细错误信息的唯一方法。因此,如果您调用 myCallback = evaluateJavascript("function() { }")
,我们将生成一个具有以下主体的函数:
try {
return eval('function() { }');
} catch(e) {
// ....
}
和return结果。
你做不到吗
x = eval('y = function() {}')
?
Attempt/Approach- 1:下面应该有效
var scope = {};
eval('scope.x = function() { return "Hello World"; }');
console.log(scope.x());
输出
Hello World
[Finished in 0.3s]
** 方法 - 2 **
在阅读了 link 上关于 IIFE 的建议后,我在下面进行了尝试 - 它似乎也有效。
var x = eval('(function() { return "Hello World"; })');
console.log(x());
但是,我意识到使用 IIFE,我们需要像 (function(){})()
这样的代码——注意尾随 ()
。但是,在 Approach-2 代码中 - 我没有尾随 ()
。然后,我查阅了 eval
文档 ,从中我了解到以下内容(这解释了 Approach-2 的工作原理):
eval as a string defining function requires "(" and ")" as prefix and
suffix
你说 var x = eval('function() { }');
应该像第一个例子一样。你为什么这么认为?你的 eval
论点
function() { }
是一个声明,如您上面指出的那样无效。你可以把它变成这样的表达式:
var x = eval('(function() { })');
- 尽可能不要使用
eval
。另一种查找错误的方法是,如果您侦听 window
(或等效)对象上的错误并将脚本导入为 <script>
s,这些脚本会立即添加和删除。
- 在
function
之前的同一行上做任何事情都会导致 function
成为一个表达式
以下都是有效的(虽然没用)
0, function () {};
(function() {});
+function () {};
-function () {};
!function () {};
// etc
像这样的函数表达式通常用于IIFEs,即
(function (foo) {
console.log(foo);
}('bar'));
// "bar" logged
但您可以将样式应用到您的 eval
-ing。括号或逗号运算符应该适合你
var code = 'function () {}';
var foo = eval('0, ' + code);
foo; // function () {}
虽然这段代码没问题:
var x = function() { };
此代码不是:
function() { };
上面的示例创建了一个匿名函数并将其分配给 x
。下面的例子是一个语句,其中需要函数名,所以是语法错误。
现在,定义一个匿名函数而不在任何地方分配它似乎毫无意义,但这里有一个面对这种行为的例子:
var x = eval('function() { }');
它的行为应该与第一个示例一样,但存在语法错误。
在我正在开发的应用程序的深处,我们遇到了这个问题。我希望 function() { }
成为一个表达式。
一个简短的解释为什么这是一个原生 OSX 应用调用 javascript 进入 WebView
。我们有一个 evaluateJavascript
函数,原生层可以使用它来调用任意 javascript。 evaluateJavascript
用 try/catch
包装给定代码以进行错误处理,因为这是获取详细错误信息的唯一方法。因此,如果您调用 myCallback = evaluateJavascript("function() { }")
,我们将生成一个具有以下主体的函数:
try {
return eval('function() { }');
} catch(e) {
// ....
}
和return结果。
你做不到吗
x = eval('y = function() {}')
?
Attempt/Approach- 1:下面应该有效
var scope = {};
eval('scope.x = function() { return "Hello World"; }');
console.log(scope.x());
输出
Hello World
[Finished in 0.3s]
** 方法 - 2 **
在阅读了 link 上关于 IIFE 的建议后,我在下面进行了尝试 - 它似乎也有效。
var x = eval('(function() { return "Hello World"; })');
console.log(x());
但是,我意识到使用 IIFE,我们需要像 (function(){})()
这样的代码——注意尾随 ()
。但是,在 Approach-2 代码中 - 我没有尾随 ()
。然后,我查阅了 eval
文档 ,从中我了解到以下内容(这解释了 Approach-2 的工作原理):
eval as a string defining function requires "(" and ")" as prefix and suffix
你说 var x = eval('function() { }');
应该像第一个例子一样。你为什么这么认为?你的 eval
论点
function() { }
是一个声明,如您上面指出的那样无效。你可以把它变成这样的表达式:
var x = eval('(function() { })');
- 尽可能不要使用
eval
。另一种查找错误的方法是,如果您侦听window
(或等效)对象上的错误并将脚本导入为<script>
s,这些脚本会立即添加和删除。 - 在
function
之前的同一行上做任何事情都会导致function
成为一个表达式
以下都是有效的(虽然没用)
0, function () {};
(function() {});
+function () {};
-function () {};
!function () {};
// etc
像这样的函数表达式通常用于IIFEs,即
(function (foo) {
console.log(foo);
}('bar'));
// "bar" logged
但您可以将样式应用到您的 eval
-ing。括号或逗号运算符应该适合你
var code = 'function () {}';
var foo = eval('0, ' + code);
foo; // function () {}