Почему использование javascript в visualvm (jhat?) Oql иногда сбивает с толку?

Мне интересно знать, почему в 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 ("function(it)" по какой-то причине обрабатывается специально в OQL?):

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

function isTrue(object) {  
  return true;  
}

Я спрашиваю об этом, потому что это кажется не интуитивным, и варианты неинтуитивного поведения появляются неожиданно и замедляют меня, когда я пытаюсь создать что-то пригодное для использования.

1 ответ

Решение

Ваши разные синтаксисы не эквивалентны. Первый:

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
Другие вопросы по тегам