Это правильно? Ошибка jQuery, которая стирает хранилище данных? - PullRequest
6 голосов
/ 29 июня 2009

Запустите консоль Firebug и попробуйте это.

Сравните это:

$('body').data('x',1);
$(thisx).remove();
console.log($('body').data('x'));

к этому:

$('body').data('x',1);
$(this.x).remove();
console.log($('body').data('x'));

Заметили разницу? Если thisx не определено, он немедленно выдаст ошибку ссылки. Если x является неопределенным свойством this, jQuery вернет документ в виде набора результатов. Далее jQuery попытается удалить ваш документ (чего не может), но перед этим удалит все данные, прикрепленные к любому дочернему элементу документа. Таким образом, уничтожая ваше хранилище данных.

Примечание: this может быть любой ссылкой на элемент или объектом. Вам нужно только, чтобы jQuery пытался получить доступ к неопределенному свойству.

(Поговорим о боли. Она молча терпит неудачу, и я пытаюсь выяснить, почему мои данные внезапно отсутствуют. Я отслеживаю это в особом случае, когда ссылка на элемент не была определена в конкретной ситуации. )

Итак, мои вопросы:

1) Перед отправкой отчета об ошибке правильно ли я анализирую это? Также, если кто-то знает, что это известная проблема, дайте мне знать. Я не смог найти его в баг-трекере, но интерфейс не так хорош (или, может быть, я ошибся).

2) Почему в конечном итоге какая-то разница? Я предполагаю, что thisx вычисляется немедленно, что вызывает исключение, в то время как this.x является ссылкой, которая передается и оценивается в вызываемой функции, верно? (где я думаю, что строка selector = selector || document; является виновником.

3) Предложения о том, как с этим справиться? Полагаю, мне следует проверить, что любая / каждая ссылка на элемент или свойство объекта (например, сохраненные селекторные строки) определены ранее Я передаю его jQuery при удалении чего-либо.

Ответы [ 2 ]

3 голосов
/ 29 июня 2009

Почему в конечном итоге какая-то разница?

И thisx, и this.x оцениваются при вызове функции. Первый ссылается на неопределенное имя переменной, и это приводит к ошибке ссылки. Второй обращается к неопределенному свойству объекта, что приводит к значению undefined. Именно так ведет себя javascript в этих случаях.

Теперь, когда JQuery вызывается во втором случае, вызов $(this.x) оценивается как $(undefined), что так же, как если бы вы просто вызвали $(). Поскольку JQuery выглядит так, как будто аргумент не был предоставлен, вместо него используется значение по умолчанию, и в этом случае значение по умолчанию - document. Затем он пытается удалить document, поскольку он фактически называется $().remove(), и в этом случае этого следовало ожидать.

Предложения, как с этим справиться?

Разница с ReferenceError является фундаментальной разницей в Javascript, с этим мало что можно сделать. Поведение JQuerys вызывает сожаление и является следствием установки значений по умолчанию arg = arg||default. Вместо этого можно было бы использовать arguments.length, чтобы получить реальное количество параметров вызова, но подобное изменение наверняка приведет к тому, что во время передачи undefined или 0 будет использоваться много сломанного кода, который полагается на значение по умолчанию, поэтому случиться.

3 голосов
/ 29 июня 2009

Попробуйте также ввести их в консоль (без дополнительных переменных, определенных заранее):

> a
    ReferenceError: Can't find variable: a
> b = {}
    Object
> b.a
    undefined

одна ошибка javascript, другая молча возвращает неопределенное значение (которое jQuery будет интерпретировать как $(), потому что javascript и jQuery не могут различать функции $() и $(undefined))

именно так работает JavaScript, ошибка или функция, которую я оставляю открытой для обсуждения, но я не думаю, что это ошибка или проблема jQuery.

edit: Почему в jQuery определено $()?

Из документов:

По умолчанию, если контекст не указан, $ () ищет элементы DOM внутри контекст текущего HTML-документа. Если вы укажете контекст, такой как Элемент DOM или объект jQuery, выражение будет сопоставлено с содержание этого контекста.

edit : документы ссылались на аргумент контекста, переданный в $(), а не на вызов $() без аргументов, поэтому здесь это не имеет значения.

также обратите внимание, что

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