Почему это незаконно в строгом режиме? - PullRequest
8 голосов
/ 01 декабря 2010

Да, да, я знаю, строгого режима еще нет, но на самом деле я планирую на будущее ...

Итак, почему это так:

$('#'+ $(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();
}

Ответы [ 2 ]

6 голосов
/ 01 декабря 2010

Метод проб и ошибок этого кода в JSLint

"use strict";
var that="dd";
function $(x){return x;}

$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
$(this);

показывает мне, что не так: вы используете this в качестве параметра.Изменение обоих this es на that s не вызывает ошибку.

Как спецификация говорит:

Если this вычисляется в коде строгого режима, тогда значение this не приводится к объекту. это значение null или undefined не преобразуется в глобальный объект, а примитивные значения не преобразуются в объекты-оболочки. это значение, переданное через вызов функции (включая вызовы, сделанные с использованием Function.prototype.apply и Function.prototype.call ), не приводят кпередал это значение объекту ( 10.4.3 , 11.1.1 , 15.3.4.3 , 15,3.4.4 ). [мой акцент]

Как Джон Резиг пишет ,

Наконец, давнишнее (и очень раздражающее)ошибка устранена: случаи, когда null или undefined принудительно становятся глобальным объектом.Строгий режим теперь предотвращает это и выдает исключение.

(function(){ ... }).call( null ); // Exception

Как вы показали, использование строки кода в объявлении функции приводит к ошибке в JSLint, тогда как использование ее внутри функциивыражение неПохоже, что JSLint ошибочно анализирует объявление функции, видит this, который в тот момент еще не определен, и выдает исключение.

На данный момент, я думаю, мне нужно процитировать Юрий Зайцев ('kangax ') :

Это действительно имеет значение?

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


Обновление: Наконец я нашелобъяснение.Если вы прочитаете эту ветку , особенно начиная с сообщения № 1512 и далее, вы прочтете, что

Смысл ES5 / strict - запретить утечку глобального объекта, чтоES3 делает беспорядочно.ES5 / strict выполняет часть своей работы динамически, а часть - статически.JSLint выполняет всю свою работу статически, поэтому он должен быть еще более ограничительным, чтобы лучше всего помочь вам в правильной реализации вашей программы. [Дуглас Крокфорд в # 1553]

Я должен признать, что он имеет здесь правильное замечание: если ваша цель - избежать загрязнения глобального пространства имен, вы не должны использовать функциюобъявления, но выражения функций внутри частного пространства имен, в любом случае.Но я согласен с другими в упомянутой теме, что сообщение об ошибке должно быть более явным (и, вероятно, выдавать предупреждение при обнаружении объявления функции).

3 голосов
/ 01 декабря 2010

После того, что сказал Дэвид Дорвард, я нашел что-то, что проходит тест JSLint. Совершенно странно, почему он это делает.

До: (см. Вопрос)

После того, как:

var displayLegend = function () {
    $('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
};

EDIT:

Я спросил Дугласа Крокфорда:

JSLint позволяет это только в строгом режиме в функциях, которые, очевидно, предназначен для вызова в качестве методов. Так написать

object.property = function () {
    ... this ...
};

Это подтверждает то, что говорится в спецификации, за исключением того, что это намного яснее!

...