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

In Javascript, how can I check if a function is in strict mode *without changing the function*?

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

An answer in a similar question 在函数定义上使用正则表达式进行检查。但是,我相信这会误检测被测试函数位于带有 "use strict" 或文件级 "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";
}

我觉得答案是"no",但是有没有办法反省一个函数,看看它是否被解析并发现是严格模式?

更新:@Amy 建议的一种方法是解析函数的源代码以找出它。如果 function 有一个 use-strict 声明(虽然它很乏味),但如果严格模式是从程序级传播的,则此方法无效;在这种情况下,我们必须将 AST 提升到程序级别并检查 that 是否为 use strict。为了使其健壮,我们必须实施所有 use 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

)

严格模式函数确实有一个 "poisoned" .caller and .arguments properties (also ES5, extra),所以你可以测试一下:

function isStrict(fn) {
    if (typeof fn != "function")
        throw new TypeError("expected function");
    try {
        fn.caller; // expected to throw
        return false;
    } catch(e) {
        return true;
    }
}