Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   объявление переменной (https://javascript.ru/forum/misc/71435-obyavlenie-peremennojj.html)

mikello 18.11.2017 12:48

объявление переменной
 
Всем привет, может кто поможет понять следующий код:

Цитата:

function Send() {

$.post("ajax.php",
{
act: "send", // указываем скрипту, что мы отправляем новое сообщение и его нужно записать
name: $("#pac_name").val(), // имя пользователя
text: $("#pac_text").val() // сам текст сообщения
},
Load); // по завершению отправки вызываем функцию загрузки новых сообщений Load()

$("#pac_text").val(""); // очистим поле ввода сообщения
$("#pac_text").focus(); // и поставим на него фокус
document.write(last_message_id);
return false; // очень важно из Send() вернуть false. Если этого не сделать то произойдёт отправка нашей формы, те страница перезагрузится
}
var last_message_id = 0; // номер последнего сообщения, что получил пользователь
var load_in_process = false; // можем ли мы выполнять сейчас загрузку сообщений. Сначала стоит false, что значит - да, можем
Несмотря на то,что переменные last_message_id и load_in_process определены после функции. document.write(last_message_id) срабатывает и выводит значение 0.

Этот код эквивалентен следующему:
Цитата:

var last_message_id = 0; // номер последнего сообщения, что получил пользователь
var load_in_process = false; // можем ли мы выполнять сейчас загрузку сообщений. Сначала стоит false, что значит - да, можем

// Функция для отправки сообщения
function Send() {

$.post("ajax.php",
{
act: "send", // указываем скрипту, что мы отправляем новое сообщение и его нужно записать
name: $("#pac_name").val(), // имя пользователя
text: $("#pac_text").val() // сам текст сообщения
},
Load); // по завершению отправки вызываем функцию загрузки новых сообщений Load()

$("#pac_text").val(""); // очистим поле ввода сообщения
$("#pac_text").focus(); // и поставим на него фокус
document.write(last_message_id);
return false; // очень важно из Send() вернуть false. Если этого не сделать то произойдёт отправка нашей формы, те страница перезагрузится
}

Почему так происходит ? Как document.write() может выводить значение переменной last_message_id, если определена она уже после функции?

Dilettante_Pro 18.11.2017 15:08

mikello,
JS сначала считывается и интерпретируется, фиксируются все определения, и уже потом исполняется. Поэтому неважно, где стоит определение переменной по порядку кода скрипта. И еще, мне кажется, вам стоит почитать про асинхронность запросов.

mikello 18.11.2017 16:26

Следующий пример выведет значение undefined (чем этот пример отличается от предыдущего? ничем,однако здесь undefined):

function a()
{
document.write(f);
}
a();
var f=0;

В предыдущем примере переменная определялась ПОСЛЕ функции, так почему она была доступна уже внутри самой функции?

Цитата:

Поэтому неважно, где стоит определение переменной по порядку кода скрипта
Вы ошибаетесь, откройте любой учебник по JS.

Dilettante_Pro 18.11.2017 19:06

mikello,
Признаю, ошибся - издержки поограммирования на нескольких языках одновременно.

В вашем первом примере переменная определена раньше, чем используется при вызове функции - типа поменяйте местами две последние строки в вашем последнем примере

mikello 18.11.2017 20:59

Я ошибся, пример на самом деле такой :

Цитата:

$(document).ready(function () {
document.write(f);
});
var f=0;
Переменная f определена после вызова функции, однако функция выводит значение 0.

Dilettante_Pro 19.11.2017 11:37

Не совсем так: переменная определяется раньше, чем выполняется функция по событию ready
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

<script>$(document).ready(function () {
console.log('Внутри');
console.log(f);
});
console.log('Снаружи');
var f=0;
</script>

mikello 19.11.2017 13:56

Теперь понятно) Спасибо.

mikello 19.11.2017 14:31

А как сделать так, чтобы сначала мы ожидали ответа от $(document).ready(function(){}), а уже потом присваивали значение 0 переменной f?

Dilettante_Pro 19.11.2017 16:17

mikello,
Присвоить значение переменной внутри document ready function

mikello 19.11.2017 17:25

Цитата:

$(document).ready(function()
{
document.write(f);
var f=0;
})
var f=1;
document.write(f)
Выводит undefined, но далее, что самое интересное не выводит 1. Каким образом добавление строки var f=0; внутри document ready function повлияло на порядок выполнения команд ? Что изменилось ?

Цитата:

$(document).ready(function()
{
alert(f);
var f=0;
})
var f=1;
alert(f);
В этом примере сначала выводится 1 , а потом уже undefined. То есть все наоборот, чем в примере выше.

Dilettante_Pro 19.11.2017 18:09

mikello,
Для отслеживания корректной аоследовательности используйте не document.write и alert, а console.log.
Тем более что второй document.write затирает предыдущий

mikello 19.11.2017 18:13

Он не затирает предыдущий, в том то и дело. Он вообще не работает.

Dilettante_Pro 19.11.2017 18:17

mikello,
Замените на console.log и посмотрите

mikello 19.11.2017 18:18

Он никогда и не затирал. Вот пример, выводит ab.

Цитата:

document.write('a');
document.write('b');

Dilettante_Pro 19.11.2017 18:24

До ready пишет в document, после - записывает все заново, затирая то,что было раньше

mikello 19.11.2017 18:27

Цитата:

$(document).ready(function()
{
document.write(f);
var f=0;
})
var f=1;
document.write(f)
То есть сначала пишет 1, а потом перезаписывает на undefined? Не уверен, что это так. Тогда бы было не undefined, а 1.

mikello 19.11.2017 18:32

Ошибся. Все правильно. Но почему здесь при втором вызове alert(f) выводится undefined, ведь переменная var f=1; уже было определено.

Цитата:

$(document).ready(function()
{
alert(f);
var f=0;
})
var f=1;
alert(f);

Dilettante_Pro 19.11.2017 18:36

Сравните первый и второй примеры и посмотрите третий

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
document.write('b');

});
document.write('a');
</script>


<script>
document.write('a');
document.write('b');
</script>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>$(document).ready(function()
{
console.log(f)
var f=0;
})
var f=1;
console.log(f)
</script>

mikello 19.11.2017 18:41

Теперь понял. А как сделать так , чтобы сначала выполнялся код в function(){}, а потом уже за ее пределами ?

Dilettante_Pro 19.11.2017 18:46

Так не получится.
Чтобы выполнялся позже, включите в конец ready function

mikello 19.11.2017 18:47

ready function и так выполняется в последнюю очередь.

mikello 19.11.2017 18:53

Цитата:

До ready пишет в document, после - записывает все заново, затирая то,что было раньше
Здесь, как я понял, речь идет в том числе и о переменной. То есть в процессе ready переменная будет undefined, даже если до этого она была определена. Я прав ?

я представляю себе работу интерпретатора на данном ниже примере так:
1) f=1;
2) вывести 1;
3) переменная f на момент выполнения ready - undefined
4)f=0
Цитата:

$(document).ready(function()
{
document.write(f); // здесь undefined
var f=0;
})
var f=1;
document.write(f) // здесь 1
То есть функция ready, когда выполняется, игнорирует предыдущие определения переменной (в данном случае f=1). Я правильно понимаю?

Dilettante_Pro 19.11.2017 19:06

mikello,
Неправильно. Уберите var f=0; в ready или поставьте в начало - и undefined исчезнет.
Дело в том, что в ready вы заново переопределяете переменную, но после использования.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>$(document).ready(function()
{
console.log(f)
})
var f=1;
console.log(f)
</script>


<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>$(document).ready(function()
{
var f=0;
console.log(f)
})
var f=1;
console.log(f)
</script>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>$(document).ready(function()
{
 f=0;
console.log(f)
})
var f=1;
console.log(f)
</script>

mikello 19.11.2017 19:13

Да, но переопределяю я ее уже после вызова document.write(f); , вот здесь непонятно почему с переменной что-то происходит и каким образом.

Интерпретатор ведь считывает все команды последовательно, так почему f=1 не имеет значения на момент document.write(f) в ready?

Почему к началу действия ready переменная имеет undefined? Она же была определена как 1. Вот что непонятно(

Dilettante_Pro 19.11.2017 19:25

Переменные имеют область видимости.
Сначала оба объявляется как глобальная переменная, внутри ready function переопределяется - глобальная в результате не видна. но значение локальная получает позже использования.

mikello 19.11.2017 19:28

А почему тогда в данном примере область видимости не имеет значения и переменная внутри ready равна 1?

Цитата:

$(document).ready(function()
{
console.log(f)
})
var f=1;
console.log(f)

Dilettante_Pro 19.11.2017 19:31

mikello,
Здесь f глобальная - объявлена вне function и не переопределяется внутри, поэтому видна ВЕЗДЕ.

mikello 19.11.2017 19:33

Цитата:

$(document).ready(function()
{
alert(f);
var f=0;
})
var f=1;
Когда мы обращаемся к alert, мы все ещё обращаемся к глобальной переменной f=1. А локальной она становится уже позже alert. Вот что непонятно.

Цитата:

$(document).ready(function()
{
var f=0
alert(f);
})
var f=1;
Вот здесь понятно, что переменная f переопределяется.

Если конкретнее - что происходит с глобальной переменной f в самом начале ready (до вызова alert())?

Цитата:

но значение локальная получает позже использования.
Так почему при использовании этой переменной выдается undefined, если она была глобальной ?

Dilettante_Pro 19.11.2017 19:51

Почитайте про глобальные обьекты в учебнике на этом форуме

mikello 19.11.2017 19:54

Как я понимаю то, что происходит с переменной f на всем участке кода:

1) f=1
2) f-undefined
3)f=0

Я не совсем понимаю при чем здесь область видимости переменной, если var f=0 идет после alert. Интерпретатор обрабатывает команды последовательно.

Вот вы говорите:
Цитата:

внутри ready function переопределяется - глобальная в результате не видна.
Но переопределяется то она после alert, или я опять чего-то не понимаю?

Цитата:

Почитайте про глобальные обьекты в учебнике на этом форуме
Прочитал, про глобальные переменные все понял, про то почему в примере выводится undefined не понял.

mikello 19.11.2017 21:36

у моего знакомого вообще undefined выводит:


рони 19.11.2017 22:08

Цитата:

Сообщение от mikello
у моего знакомого вообще undefined выводит:

в данном коде нет глобальной переменной, нажать кнопку javascript выбрать нужное в Load type (последний пункт in body)

mikello 19.11.2017 22:15

а как должен выглядеть этот код с глобальной переменной?

рони 19.11.2017 22:36

Цитата:

Сообщение от mikello
а как должен выглядеть этот код с глобальной переменной?

также как у вас, только без обёртки в load настройте песочницу как написано выше.

рони 19.11.2017 22:44

mikello,
сейчас ваш код выглядит на самом деле так
window.onload=function(){
$(document).ready(function() {
alert(f);
});
var f = 1
}

mikello 19.11.2017 22:47

window.load вызывается, когда все элементы страницы загружены. Что это меняет по сути ? Почему переменная var f=1 перестала быть глобальной?

mikello 19.11.2017 22:49

у меня ваш код выводит 1

рони 19.11.2017 22:52

Цитата:

Сообщение от mikello
Почему переменная var f=1 перестала быть глобальной?

потому что находится внутри функции.

mikello 19.11.2017 22:52

но у меня выводится 1

рони 19.11.2017 22:55

mikello,
:-?
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
window.onload=function(){
$(document).ready(function() {
alert(f);// undefined 
});
var f = 1;
}
  </script>
</head>

<body>


</body>
</html>


Часовой пояс GMT +3, время: 03:31.