在Javascript中,如何在不更改函数的情况下检查函数是否处于严格模式*?

在Javascript中,如何在不更改函数的情况下检查函数是否处于严格模式*?,javascript,strict,Javascript,Strict,我想编写一个测试套件,以确保某些给定函数使用严格模式。它们有很多,手动检查它们似乎是一件苦差事 对函数的定义使用正则表达式进行检查。但是,我相信这会错误地检测到被测试函数位于具有“use strict”或文件级“use strict”声明的函数内的情况。答案是“严格使用”是预先指定的,但在我的环境(Mozilla Rhino)中,情况并非如此: $ cat strict_sub.js "use strict"; var strict_function = function() { not

我想编写一个测试套件,以确保某些给定函数使用严格模式。它们有很多,手动检查它们似乎是一件苦差事

对函数的定义使用正则表达式进行检查。但是,我相信这会错误地检测到被测试函数位于具有“use strict”或文件级“use strict”声明的函数内的情况。答案是“严格使用”是预先指定的,但在我的环境(Mozilla Rhino)中,情况并非如此:

$ 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坏了。