разница между 'var a = 2' и 'this.a = 2' - PullRequest
2 голосов
/ 17 ноября 2010

Я только что обнаружил самую странную ошибку в некотором коде javascript, касающемся RegExp.test. У меня было регулярное выражение regexp, объявленное внутри функции, и у меня было замыкание со ссылкой на regexp, и я использовал замыкание для перебора массива строк, чтобы проверить их с помощью collect из прототипа .js, то есть

function some_func() {
  var regexp = /regular_expression/;
  an_array_of_strings.collect(
     function(str) {
       if (regexp.test(str)) {
         do_something();
       }
     }
  );
}

Действительно странной вещью было то, что вызов regexp.test(str) внутри замыкания будет чередоваться между true и false на одном и том же входе. Я посмотрел на источник для RegExp.test и не увидел ничего подозрительного, но что-то происходило, потому что как одна и та же строка может пропускать одно и то же регулярное выражение. Посмотрев еще на RegExp.test, я в основном пришел к выводу, что переменные, объявленные в RegExp.test, продолжают существовать между вызовами и портят последующие вызовы. Итак, вот вопрос: в чем разница между

this.a = 2;

и

var a = 2;

когда вышеприведенные операторы появляются внутри метода, вызываемого для объекта внутри замыкания, которое содержит ссылку на этот объект? Я спрашиваю, потому что ошибка исчезает, когда я перемещаю regexp.test за пределы закрытия. Когда regexp.test вызывается вне замыкания, он не переключается между true и false при каждом вызове. Я понятия не имею, почему это происходит.

Редактировать : Когда я перемещал regexp за пределы замыкания, я забывал добавить глобальную опцию, поэтому ошибка исчезла. Спасибо Иво .

Ответы [ 3 ]

3 голосов
/ 17 ноября 2010

Поскольку вы не показывали свой RegExp, но я только что ответил на что-то похожее на это, я полагаю, что вы используете опцию global в вашем RegExp, которая имеет некоторые интересные побочные эффекты.

Как с exec (или в комбинации с это), тест вызывается несколько раз на то же глобальное регулярное выражение Экземпляр продвинется мимо предыдущий матч.

Источник: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test

Итак, что именно здесь происходит, так это то, что, поскольку вы используете глобальный параметр для регулярного выражения, он продолжит поиск строки после того, как найдет совпадение.

regexp.test("d")

Это найдет d в позиции 0 .

regexp.test("d")

Теперь будет выполняться поиск d, начиная с позиция 1 , но, поскольку это конец строки, он ничего не найдет, поэтому возвращает false .

Мы можем использовать свойство lastIndex регулярного выражения, чтобы доказать, что:

regexp.lastIndex
>> 0
regexp.test("d")
>> true
regexp.lastIndex
>> 1
regexp.test("d")
>> false

Таким образом, чтобы решить эту проблему, вам нужно удалить опцию global из вашего RegExp.

Отказ от ответственности, это копия моего предыдущего ответа:
Необычный javascript результат Regex, объяснение пожалуйста!

1 голос
/ 17 ноября 2010

Посмотрите на эту страницу о чудесах this в JS.Значение this довольно сильно меняется в зависимости от того, как вы используете свои функции.

1 голос
/ 17 ноября 2010

Это сложный вопрос, так как на первый взгляд они кажутся идентичными.

Я бы предположил, что this.a принадлежит функции, но может также продлевать жизнь этой функции, а не только сам вызов функции; тогда как var a будет создаваться и уничтожаться при каждом выполнении функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...