Будет ли этот фрагмент обнаружения цикла for-in генерировать нежелательные ложные срабатывания?
Мы все знаем, что циклы for в массивах абсолютно злые. Тем не менее, они часто используются, и вызванные ошибки сложно отследить, особенно когда они зависят от браузера, например, из-за indexOf
Шимс или тому подобное.
Итак, я кодировал этот простой фрагмент, который добавляет перечислимый геттер для "error
"собственность на Array.prototype
(не для использования в производственном коде):
Object.defineProperty(Array.prototype, "error", {
enumerable: true,
get: function() {
if (this === Array.prototype) // that looks OK
return undefined;
if (window.confirm("Somebody who coded the site you're viewing runs through an Array with a for-in-loop.\nShame on him!\n\nDo you want to raise an Error to trace the origin?"))
throw new SyntaxError("Array traverse with for-in-loop, touching Array.prototype's 'error' property :-)");
}
});
Вы можете добавить его как скрипт greasemonkey для всех доменов, и вы увидите предупреждения почти на каждом сайте:-) Большинство из них вызваны вызовами jQuery.extend
с сомнительными аргументами, кстати.
Мой вопрос сейчас: есть ли ситуации, которые оправдывают такие "неправильные" циклы, или что-то еще, вызывающее ложно-положительные оповещения?
Мне интересно, как это повлияет на полезность моего кода.
1 ответ
Да. Легитимность часто может быть субъективной, но...
В качестве примера, возможно, у меня есть разреженный массив, где я только установил значения в индексах с данными:
var a = [];
a[123123] = "foo";
a[1233123] = "bar";
Если бы я хотел перебрать элементы, которые я определил в этом массиве, то я бы использовал for...in
построить. Даже если бы я закодировал это в обороне, ваш сценарий все равно сработал бы (ложное срабатывание)...
for (var prop in a) {
if (a.hasOwnProperty(prop)) {
// this is a legitimate array element
}
}
См. Также Почему использование "for...in" с итерацией массива - плохая идея? для получения дополнительной информации и мнений.