Почему использование strict не соблюдает область видимости переменных

У меня есть вопрос относительно использования переменных "use strict".

Почему следующее происходит без ошибок, а не выдает ошибку?

"use strict"; 
var $class = {};
$class.rowsICanDisplay = 10;
$class.difference = -1;
var absDifference = 1;
var gridTableBody = $('#mytable tbody');
//code removed for clarity
if($class.difference > 0) {
    var offset = $class.rowsICanDisplay - absDifference; // mistake should be declared in outer scope
    //code removed for clarity
    $('tr:lt(' + offset + ')', gridTableBody).remove();
}
else {
     //code removed for clarity
     $('tr:gt(' + offset + ')', gridTableBody).remove(); // why does this fail silently
}

person Katlyn Anne Fairlamb    schedule 11.03.2014    source источник
comment
Потому что Javascript не имеет блочной области. Извини. Однако JSHint поймает это.   -  person SLaks    schedule 11.03.2014
comment
@EricHerlitz - извините, исправил это (на самом деле это не было проблемой в реальном коде).   -  person Katlyn Anne Fairlamb    schedule 11.03.2014
comment
@SLaks - ах, я вижу, это довольно расстраивает, поскольку выглядит так, как есть. Думаю, я сделаю задачу после сборки для запуска JSHint, тогда спасибо. (если вы напишете это как ответ, я сделаю его выбранным)   -  person Katlyn Anne Fairlamb    schedule 11.03.2014
comment
Область JavaScript функциональна. Переменные внешней области доступны во внешней области, и они доступны для любых функций в этой области.   -  person Alex W    schedule 11.03.2014
comment
В качестве примечания я бы посоветовал вам избегать использования $ перед именами ваших переменных. Это больше похоже на PHP, и его легко спутать с jQuery.   -  person Alexis Wilke    schedule 12.03.2014
comment
ах, это просто потому, что class - зарезервированное слово, возможно, было бы лучше назвать его thisClass, как вы думаете? так как в моей фактической кодовой базе это указатель на функцию, которая используется классом...   -  person Katlyn Anne Fairlamb    schedule 13.03.2014


Ответы (3)


Поскольку Javascript не имеет блочной области видимости.
Любая переменная, объявленная где-либо в функции, видна всей функции.

JSHint уловит эту проблему.

person SLaks    schedule 11.03.2014

$('tr:gt(' + offset + ')', gridTableBody).remove(); // why does this fail silently

Поскольку offset не определено в контексте вашего блока else, ваш селектор недействителен и ничему не соответствует.

person Madbreaks    schedule 11.03.2014
comment
Но это не должно выдавать ошибку, потому что она не определена, потому что предполагается, что использование strict должно защищать от использования неопределенных переменных. - person Katlyn Anne Fairlamb; 11.03.2014
comment
var offfset = ... определяет переменную глобально, поэтому else видит, что она определена, хотя значение будет неопределенным. - person Alexis Wilke; 12.03.2014
comment
только javascript может иметь определенную переменную со значением undefined ... если это не сбивает с толку терминологию idk, что есть, также возникает вопрос о том, что называть переменной переменной, которая не определена (под этим я имею в виду без var х = ...;. - person Katlyn Anne Fairlamb; 13.03.2014
comment
@AlexisWilke Различие, на которое вы указываете, бессмысленно с точки зрения JavaScript: невозможно отличить объявленную, но не определенную переменную от необъявленной переменной. typeof offset приведет к "undefined" в блоке else. - person Madbreaks; 14.03.2014
comment
@Madbreaks, если вы прочитаете ответ SLaks, вы увидите, что то, что я говорю, не совсем не соответствует цели. Переменная инструкция определяет переменную для этой функции (или в глобальном масштабе, если вы не находитесь в функции), независимо от того, получает ли она значение или нет, и где бы она ни появлялась в функции. Вот почему пользователь strict не реагирует. Лучше всего объявить все ваши переменные вверху, как в C. - person Alexis Wilke; 15.03.2014

В операторе else смещение не определено. Вам нужно вытащить его и определить вне структуры «если».

person Brent Echols    schedule 11.03.2014
comment
Это неправильно. В JavaScript нет области видимости блока; в этом отношении он отличается от Java и C++. Все операторы var обрабатываются так, как если бы они находились в начале функции. - person Pointy; 11.03.2014
comment
Да, я понимаю это, но для того, чтобы он был определен, когда он попадает в оператор else, ему нужно его вытащить. Я не говорю, что применяется новая область видимости, а скорее ему нужно подтянуть ее к месту, которое дало бы этой переменной определение до использования: p - person Brent Echols; 11.03.2014
comment
О верно; Я вижу, что ты говоришь. Это не неверно в строгом режиме, но неверно, потому что выражение инициализации var не выполняется в ветке else! - person Pointy; 12.03.2014