Var x = x || "default val" не устанавливается должным образом, если x определено над ним

HTML:

<script type="text/javascript">
  var x = "overriden";
</script>
<script src="myjs.js"></script>

myjs.js:

$(document).ready(function(){
  var x = x || "default val";
  alert(x); // this alerts "default val" and not "overriden"
});

По какой-то причине x заканчивается как "default val", а не "overriden", даже изначально я устанавливаю его на "overriden", прежде чем даже включить ссылку script на myjs.js.

Любая идея, почему это происходит? Я пытаюсь включить страницу хостинга для установки переопределения для переменной, которая используется во включенном файле js, иначе используйте значение по умолчанию.

Ответ 1

То, что у вас есть после подписи объявления переменной:

var x;
x = 5;

$(document).ready(function(){
    var x;
    x = x || "default";
});

Он смотрит на ближайший x и видит, что значение undefined является ложным значением, поэтому x устанавливается в "default".


 Вы были бы в порядке, если бы они были в одном и том же объеме, потому что объявления всегда поднимались над присваиваниями так:
var x = 5;

var x = x || "default";

На самом деле просто

var x;

x = 5;
x = x || "default";

Было высказано предположение, что совершенно бессмысленно:

$(document).ready(function(){
    x = x || "default";
});

Он выкинет ReferenceError, если x не определен.


Так что либо сделайте проверку в том же объеме, либо выполните что-то вроде:
$(document).ready(function(){
    var x = window.x || "default";
});

Недопустимые чтения свойств не вызывают ReferenceError, а просто возвращают undefined.

Ответ 2

Функция var x в функции, переданной в $(document).ready(), скрывает глобальную переменную x.

Если вы просто используете x = x || "default val";, тогда глобальная переменная будет сбита. Тем не менее, это действительно плохая идея иметь глобальные переменные вообще.

Ответ 3

В обоих местах используется ключевое слово var. Попробуйте:

x = x || "default val";

https://developer.mozilla.org/en/JavaScript/Reference/Statements/var

Из приведенной выше ссылки:

Объем переменной, объявленной с помощью var, является закрывающей функцией или для переменных, объявленных вне функции, глобальной области (которая привязан к глобальному объекту).

Ответ 4

Потому что вы снова объявляете новый var x внутри document.ready(), который является еще одной областью, кроме глобальной. Попробуйте это

$(document).ready(function(){
  x = x || "default val";
  alert(x); // this will now alert "overriden"
});

Ответ 5

x не определяется в рамках функции document ready.

var x готовит переменную со значением undefined, поэтому она не получит ее из области окна.

Попробуйте var x = x || window.x || "default val";.

Ответ 6

Поскольку вы указали это с помощью var, который не получает глобально определенный объект из html. Попробуйте удалить var и посмотреть, получится ли у вас другой результат или измените переменную внутри функции на другую букву.

Когда вы используете var внутри функции, область действия этого var является только функцией. Поскольку вы дважды определили переменную x, когда вы выполняете сравнение, она пытается использовать переменную из функции.

Если вы планируете хранить инструкцию var, вам нужно будет изменить имя переменной или как вы вызываете глобальный x до window.x. Другой вариант - просто удалить var из функции.

Ответ 7

x, созданный в этой строке:

var x = x || "default val";

... является локальным для функции, определенной в (т.е. тени глобальной x).

Удаление предыдущего var приведет к тому, что имена обоих x будут ссылаться на одну и ту же глобальную переменную, но это, как правило, плохая идея. На ранее связанной странице Википедии:

Это может привести к путанице, так как может быть неясно, какая переменная последующее использование имени теневой переменной относится к.

Ответ 8

Вы объявляете var x в своей функции, которая создает локальное хранилище для x и скрывает предыдущие значения.

Назовите его var y или сделайте так, как предположил karim79.

Ответ 9

Ваш var x во втором локален для этой функции и не совпадает с window.x (это то, что вы определили в предыдущем блоке).

Ответ 10

ключевое слово var означает, что вы только что создали локальную переменную. Так что в основном происходит то, что:

  • Вы объявляете (в своем первом блоке) x как "переопределенный"

Память:

 x -> "overriden"
  • Вы устанавливаете обратный вызов document.ready

Память:

 x -> "overriden"

(после загрузки документа) 3. Вы запускаете свою анонимную функцию, инициализируя x с помощью var

Память:

x->"overriden"
[IN SCOPE]
anonymous_function.x -> "default_value"
[/SCOPE]

"НО ЖДАТЬ" , вы можете сказать: "Код, который я написал, это var x= x || "default var", так что должно произойти: local_x=global_x || "default value, правильно?

Вряд ли Javascript не работает. В javascript у нас есть область функций, а не более широко используемая область блоков. Поэтому, когда вы пишете:

f=function(){
    var x=y || "default value";
    var y=3;
    alert(x);
} 

что будет интерпретироваться в javascript:

f=function(){
    var x;
    var y;
    x=y || "default value";
    y=3;
    alert(x);
}

поэтому запуск y=10; f(); даст вам "значение по умолчанию" в приглашении.


Таким образом, снятие вашего var будет работать, чтобы исправить вашу проблему здесь, но просто помните, в общем, что все ваши объявления переменных выполняются "в начале" функции, поэтому область видимости сразу изменяется при вводе функции.