Почему это незаконно в строгом режиме?
-
29-09-2019 - |
Вопрос
Да, да, я знаю, строгий режим еще нет рядом, но на самом деле я планирую на будущее ...
Итак, почему это:
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
... не разрешен в строгом режиме ES5?
Или я неверно истолковываю? Jslint:
Problem at line 516 character 18: Strict violation.
Может ли это быть немного более многословным, интересно ...?
РЕДАКТИРОВАТЬ:
Чтобы избежать путаницы, вот больше исходного кода:
function displayLegend() {
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
}
Решение
Некоторая пробная и ошибка этого кода в Jslint
"use strict";
var that="dd";
function $(x){return x;}
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
$(this);
Показывает мне, что не так: вы используете this
как параметр. Изменение оба this
ES TO that
S не запускает ошибку.
В виде спецификация говорит:
Если это оценивается в строгом коде режима, затем это Значение не принуждается к объекту. А. это ценность нулевой или неопределенный не преобразуется в глобальный объект, а примитивные значения не преобразуются в объекты обертки. То это значение, передаваемое с помощью функционального вызова (включая вызовы с использованием Function.prototype.apply и Function.prototype.call) не принуждайте пройти это значение для объекта (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4). Мой акцент
Как Джон Ресиг пишет,
Наконец, была разрешена давняя (и очень раздражающая) ошибка: случаи, когда нулевые или неопределенные принуждаются стать глобальным объектом. Строгий режим теперь предотвращает это, и вместо этого бросает исключение.
(function(){ ... }).call( null ); // Exception
Как вы показали, использование вашей строки кода внутри функционального объявления выбрасывает ошибку в JSLINT, тогда как использование ее внутри функции выражение не является. Похоже, что jslint ошибочно анализирует объявление функции, видит this
, это все еще не определено в тот момент и бросает исключение.
На данный момент, я думаю, мне нужно процитировать Juriy Zaytsev ('kangax'):
Это действительно имеет значение?
Приятно понимать, что Строгий режим не является требованием, но это просто вариант. Он должен предоставить более строгие правила для тех, кто в нем нуждается, и готовы справиться (и наслаждаться) последствиями.
Обновлять: Наконец я нашел объяснение. Если вы читаете эта ветка, особенно с сообщения № 1512, вы прочитаете это
Смысл ES5/Strict заключается в том, чтобы запретить утечку глобального объекта, что ES3 не беспорядочно. ES5/Strict выполняет некоторые из своих работ динамически, а некоторые из своих работ статически. JSLINT выполняет всю свою работу по статически, поэтому она должна быть еще более ограничительной, чтобы лучше всего помочь вам правильно понять свою программу. Дуглас Крокфорд в #1553
Я должен признать, что у него есть достоверная точка зрения: если ваша цель состоит в том, чтобы избежать глобального загрязнения пространства имен, вы не должны использовать объявления функций, но в любом случае выражения функций внутри частного пространства имен. Но я согласен с другими в упомянутом потоке, что сообщение об ошибке должно быть более явным (и, вероятно, бросить предупреждение о встрече с объявлением функции).
Другие советы
После того, что сказал Дэвид Дорвард, я нашел что -то, что проходит тест JSLINT. Это совершенно странно, почему это делает это.
До: (см. Вопрос)
После:
var displayLegend = function () {
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
};
РЕДАКТИРОВАТЬ:
Я спросил Дугласа Крокфорда:
JSLINT позволяет только в строгом режиме в функциях, которые, очевидно, предназначены для того, чтобы их называли методами. Так напиши
object.property = function () { ... this ... };
Это подтверждает то, что говорит в спецификации, за исключением того, что это намного яснее!