【问题标题】:In Javascript, how can I check if a function is in strict mode *without changing the function*?在Javascript中,如何检查函数是否处于严格模式*而不更改函数*?
【发布时间】:2016-03-07 05:15:31
【问题描述】:

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

An answer in a similar question 在函数定义上使用正则表达式进行检查。但是,我相信这会错误地检测到正在测试的函数位于具有“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 建议的一种方法是解析函数的源代码以找出答案。如果 function 有一个 use-strict 声明(虽然它很乏味),则此方法有效,但如果严格模式是从程序级别传播的,则此方法无效;在这种情况下,我们必须将 AST 提升到程序级别并检查 that 是否有 use strict。为了使它更健壮,我们必须实现 use strict-propagation 的所有规则,而解释器已经在某个地方拥有这些规则。

(在 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

)

【问题讨论】:

  • 我通常使用这个: var isStrict = (function() { return !this; })(); console.log(isStrict);
  • @Shakawkaw:但这需要在要测试的函数内部运行。我需要在外部对其进行测试。
  • "有没有办法自省函数看是否被解析后发现是严格模式"没有。
  • 必须自己解析(例如使用 Spidermonkey Parser API)并检查生成的 AST,否则。
  • @Amy:我尝试使用 Spidermonkey 进行解析,但它实际上只告诉我(例如)那里有一个字符串文字。如果有文件级别的严格,我也必须自己检查。

标签: javascript strict


【解决方案1】:

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

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

【讨论】:

  • 规格来源会很有用。
  • 天哪,我把 Function .caller 与具有这些中毒属性的 arguments 对象 混淆了(@BenAston:ES5ES6
  • @BenAston:哦,我只是偶然发现了它:严格模式的函数对象实际上也有中毒的属性
  • 我只是不确定这是否仍然适用于 ES6,其中这些中毒的属性似乎是从 Function.prototype 继承的,因此如果环境不创建非-为他们提供标准自己的属性。
  • 不确定我是否完全遵循,但我实现了您的功能并进行了一些测试。在 Spidermonkey 中,效果很好。在 Rhino 中,看起来像 function.caller is not implemented :( 即使你的答案在 Rhino 中不起作用,我认为是 Rhino 坏了。
猜你喜欢
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2010-11-05
  • 2013-10-08
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
相关资源
最近更新 更多