为什么在visualvm(jhat?)oql中使用javascript有时令人困惑?

时间:2011-12-10 21:56:47

标签: javascript visualvm oql jhat

我很想知道为什么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(注意“它”被引用):

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

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

示例3(“函数(it)”由于某种原因在OQL中专门处理?):

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

function isTrue(object) {  
  return true;  
}

我问这个是因为它看起来不直观,非直觉行为的变化出现意外,当我试图创造可用的东西时,我的速度会慢下来。

1 个答案:

答案 0 :(得分:5)

您的不同语法等效。第一个:

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

使用参数isTrue调用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