Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以通过编程方式检测闭包?_Javascript_Closures - Fatal编程技术网

Javascript 是否可以通过编程方式检测闭包?

Javascript 是否可以通过编程方式检测闭包?,javascript,closures,Javascript,Closures,我有一个允许用户传递函数的函数 function withPredicate(func){ //... } 在我的函数中,我需要检测用户传入的func是否有闭包 仅获取函数名并在窗口范围中搜索它是不够的。用户可能会传入匿名函数而不使用闭包,如: var func = function(x){return x;}; withPredicate(func); 编辑: 我想我需要实现一个函数,它将函数作为参数并返回bool function hasClosure(func){ //

我有一个允许用户传递函数的函数

function withPredicate(func){
    //...
}
在我的函数中,我需要检测用户传入的func是否有闭包

仅获取函数名并在窗口范围中搜索它是不够的。用户可能会传入匿名函数而不使用闭包,如:

var func = function(x){return x;};
withPredicate(func);
编辑:

我想我需要实现一个函数,它将函数作为参数并返回bool

function hasClosure(func){
    //...
}
因此,有几个测试用例是:

hasClosure(function(x){return x;}); //return false

var something = 30;
var func1 = function(x){return x.age < something;} 
hasClosure(func1);   //return false

var Closure = function(){
    var something = 18;
    var itself = function(x){
        return x.age < something;
    };
    return itself;
};

var func2 = new Closure();
hasClosure(func2); //return true
最后一个返回true,因为func2不是顶级函数。当我在函数体中看到一些自由变量时,它可能会解析为闭包中定义的变量,而不是窗口中定义的变量

实际上,我现在需要做的是基于传递给我的函数的func进行一些操作。我可以使用JSLint获取未声明的变量。但我也需要解决这些变量。我只能在全局范围内解析变量,这是可以接受的。但我仍然需要一种方法来确保在全局范围内解析这些变量是正确的。所以我需要检测闭包


是否可以在javascript中通过编程实现这一点?

正确的答案在很大程度上取决于闭包在此上下文中的含义。问题中的函数不使用外部范围中的变量,因此,大致上,不会为此函数创建闭包。但严格来说,闭包是为任何函数创建的,并将定义上下文和函数绑定在一起。因此,无论您想要检测什么,都需要一个详细的规范


但是我可以假设这里的闭包意味着函数是否引用了在外部范围中声明的变量,就像指定的一样。其中一个用于分析的静态库可用于此目的。例如,JSLint报告使用但未声明的变量。假设未声明的变量仅来自上限范围,这表示已创建闭包。

好吧,这真的很有意思,可能不值得实际编写,除非您的linting或其他内容:

基本上,要确定函数是否为闭包,需要做的是调用func.toString,它将为您提供函数的源。然后可以使用某种解析器解析函数,该解析器确定函数func的所有变量。您还需要确定和跟踪这些变量的定义方式。在op中的条件中,作为闭包的条件是有一个在函数范围外和窗口范围外定义的变量,因此是闭包范围。所以,如果你能找到这两个作用域之外定义的变量,我们就找到了一个闭包

下面是HasClose的伪代码,请享受实现的乐趣

func hasClosure(func)
   source = func.toString(); //eg "function x(a) {return new Array(a)}"
   variables = parseJSForVariables(source)//finds a and Array
   for variable in variables:
      if(variable not in window)
          if(variable not defined in function)
              return true //we got a closure
  return false //not a closure

没有本机扩展就不行。函数的作用域链不会在语言中公开以进行响应。不过,出于好奇,为什么您需要知道函数是否具有与之相关联的作用域?也许吧?你对闭包的定义是什么?如果你想让事情变得真实,你可以把func.toString切碎weird@StarPinkER:您需要检测闭包的原因是什么?检查给定的功能是否没有副作用?闭包和无闭包函数之间应该没有功能上的区别——这意味着您不应该能够检测到它。语义闭包可以通过分析源代码来检测,但在运行时环境中不能检测,因为运行时环境只知道成员在范围内或不在范围内。在js引擎内部的某个地方,每个执行上下文都必须有一些标志,这些标志会导致GC被抑制,但很抱歉,它是不可访问的。很抱歉,我没有准确地描述我的问题。我更新了我的帖子,你能看一下吗?好的。如果您使用JSLint.com检查函数闭包,并关闭空格和其他不相关的检查,您将看到函数报告。报告包括内部函数、其参数和使用的外部变量。在我看来,分析此报告是构建函数是否包含闭包的标准的好方法。当然,您可以为代码中的任何函数生成此报告-有关详细信息,请参阅JSLint文档。但问题是,我只能将用户提供给我的函数传递给JSLint。所以JSLint对函数是如何构建的一无所知。正如另一个答案中提到的,使用函数的.toString方法获取其源代码。如果我在窗口中找到一个变量,但它仍然有一个外部函数作用域,该怎么办?就像我的上一个例子,你根本不可能知道,javascript并没有向你传递函数范围的任何信息,这就是为什么这是真正的黑客行为