在Javascript中,如何在不更改函数的情况下检查函数是否处于严格模式*?
我想编写一个测试套件,以确保某些给定函数使用严格模式。它们有很多,手动检查它们似乎是一件苦差事 对函数的定义使用正则表达式进行检查。但是,我相信这会错误地检测到被测试函数位于具有“use strict”或文件级“use strict”声明的函数内的情况。答案是“严格使用”是预先指定的,但在我的环境(Mozilla Rhino)中,情况并非如此:在Javascript中,如何在不更改函数的情况下检查函数是否处于严格模式*?,javascript,strict,Javascript,Strict,我想编写一个测试套件,以确保某些给定函数使用严格模式。它们有很多,手动检查它们似乎是一件苦差事 对函数的定义使用正则表达式进行检查。但是,我相信这会错误地检测到被测试函数位于具有“use strict”或文件级“use strict”声明的函数内的情况。答案是“严格使用”是预先指定的,但在我的环境(Mozilla Rhino)中,情况并非如此: $ cat strict_sub.js "use strict"; var strict_function = function() { not
$ cat strict_sub.js
"use strict";
var strict_function = function() {
not_a_real_global = "foo";
};
print(strict_function);
$ rhino strict_sub.js
function () {
not_a_real_global = "foo";
}
我觉得答案是“否”,但是否没有办法内省一个函数,看看它是否被解析并发现是严格模式
更新:@Amy建议的一种方法是解析函数的源代码来找出它。如果函数有一个use strict声明(虽然它很乏味),那么它就可以工作,但是如果严格模式是从程序级传播的,那么它就不能工作;在这种情况下,我们必须走到AST的程序级,检查是否使用strict
。为了使其健壮,我们必须实现使用严格的传播的所有规则,解释器已经在某个地方实现了这些规则
(在SpiderMonkey中测试:
function f() {
"use strict";
}
var fast1 = Reflect.parse(f.toString());
var first_line = fast1.body[0].body.body[0].expression;
print(first_line.type === 'Literal' && first_line.value === 'use strict'); //true
)严格模式函数确实有一个(也有,),因此您可以测试:
function isStrict(fn) {
if (typeof fn != "function")
throw new TypeError("expected function");
try {
fn.caller; // expected to throw
return false;
} catch(e) {
return true;
}
}
我通常使用这个:var isStrict=(function(){return!this;})();控制台日志(isStrict)@Shakawkaw:但这需要在要测试的函数内部运行。我需要对它进行外部测试。“有没有办法内省一个函数,看看它是否被解析并发现是严格模式”没有。没有。没有自己解析它(比如使用Spidermonkey解析器API)并检查生成的AST,没有。@Amy:我试着用Spidermonkey解析,但它实际上只告诉我这一点(例如)这里有一个字符串文本。如果有严格的文件级,我也必须自己检查。规范源代码会很有用。噢,该死,我把参数
对象弄糊涂了,它确实有这些有毒属性(@BenAston:,)@BenAston:Oh,我只是偶然发现了它:严格模式函数对象实际上也有有毒属性。我只是不确定这是否仍然适用于ES6,因为这些有毒属性似乎是从函数继承而来的。prototype
,因此,即使是草率模式的函数,如果环境没有为它们创建非标准的自己的属性,也可能会有它们。我不确定我是否完全遵循,但我实现了您的函数并进行了一些测试。在Spidermonkey中,效果很好。在Rhino中,似乎:(虽然你的答案在Rhino中不起作用,但我认为是Rhino坏了。