2

我很想知道为什么 visualvm OQL 对以下语句有问题:

select filter(heap.objects("java.util.HashMap"), isTrue(it));

function isTrue(object) {  
  return true;  
}

例外是:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "it" is not defined. (#1)

相比之下,visualvm OQL 对以下任何示例都没有问题:

示例 1(注意“它”没有被引用):

select filter(heap.objects("java.util.HashMap"),  
    function(it) {  
      return true;  
    });

示例 2(注意“it”被引用):

select filter(heap.objects("java.util.HashMap"), isTrue("it"));  

function isTrue(object) {  
  if (object instanceof String) {  
    throw "String passed!";  
  }  
  return true;  
}

示例 3(“function(it)”出于某种原因在 OQL 中特别处理?):

select filter(heap.objects("java.util.HashMap"), function(it) { return isTrue(it); });

function isTrue(object) {  
  return true;  
}

我问这个是因为它似乎不直观,并且当我尝试创建可用的东西时,非直观行为的变化会出乎意料地出现并减慢我的速度。

4

1 回答 1

5

您的不同语法等效。首先:

select filter(heap.objects("java.util.HashMap"), isTrue(it));

isTrue使用参数 of调用it并将其结果传递给filter()函数。那时您没有it定义变量,因此出现错误。

您的“示例 1”和“示例 3”都将函数作为第二个参数传递给filter()函数。您传入的函数(可能)旨在作为filter()将调用的回调,其中参数it将由filter().

您的“示例 2”有点像第一个代码,它isTrue("it")立即调用,但在这种情况下,它使用字符串文字调用它,因此您不会遇到未定义参数的问题。然而,这同样是将函数的结果作为参数传递给filter()而不是传递函数本身。

的正确用法filter()是向它传递一个函数(函数引用 -不带括号的函数的名称 - 或像“示例 1”中的函数表达式)。所以尝试以下方法:

select filter(heap.objects("java.util.HashMap"), isTrue);

function isTrue(object) {  
  return true;  
}

// OR your example 1
于 2011-12-11T00:39:21.733 回答