Loading...

Эскирген "var" ачкыч сөзү

Эскирген "var" ачкыч сөзү

 

Өзгөрмөлөр жөнүндөгү биринчи бөлүмдө биз өзгөрмөлөрдү жарыялоонун үч жолу менен тааныштык:

  1. let
  2. const
  3. var

letжана constлексикалык чөйрөгө, чөйрөгө карата бирдей мамиле кылуу.

Бирок var- бул такыр башка жырткыч, байыркы убактан бери келип чыккан. Көбүнчө varзаманбап скрипттерде колдонулбайт, бирок эскилеринде дагы деле жашырылышы мүмкүн.

Эгерде сиз азыр мындай скрипттер менен иштебесеңиз, анда бул бөлүмдү окууну өткөрүп жиберсеңиз же кийинкиге калтырсаңыз болот, бирок келечекте сизди жолуктура турган мүмкүнчүлүк бар var.

Бир караганда, жүрүм-туруму varокшош let. Мисалы, өзгөрмө декларациясы:

 
 
@A@function sayHi() {
  var phrase = "Привет"; // локальная переменная, "var" вместо "let"

  alert(phrase); // Привет
}

sayHi();

alert(phrase); // Ошибка: phrase не определена@A@

…Бирок, айырмачылыктар бар.

"var" үчүн блоктоо аймагы жок

Өзгөрмөлөрдүн чөйрөсү varфункция менен же өзгөрмө глобалдуу болсо, сценарий менен чектелет. Мындай өзгөрмөлөр блоктон тышкары жеткиликтүү.

Мисалы:

@A@if (true) {
  var test = true; // используем var вместо let
}

alert(test); // true, переменная существует вне блока if@A@

Ал varблокторго көңүл бурбагандыктан, биз глобалдык өзгөрмө алдык test.

Эгерде биз let testанын ордуна колдонсок var test, анда өзгөрмө ичинде гана көрүнөт if:

@A@if (true) {
  let test = true; // используем let
}

alert(test); // Error: test is not defined@A@

Ошо сыяктуу эле, циклдер үчүн: varцикл ичинде блокко же жергиликтүү болушу мүмкүн эмес:

@A@for (var i = 0; i < 10; i++) {
  // ...
}

alert(i); // 10, переменная i доступна вне цикла, т.к. является глобальной переменной@A@

Эгерде код блогу функциянын ичинде болсо, анда varал ошол функцияда жергиликтүү өзгөрмө болуп калат:

@A@function sayHi() {
  if (true) {
    var phrase = "Привет";
  }

  alert(phrase); // срабатывает и выводит "Привет"
}

sayHi();
alert(phrase); // Ошибка: phrase не определена (видна в консоли разработчика)@A@

Биз көрүп тургандай, ал varблоктордун чегинен чыгып кетет жана башкалар. Себеби, JavaScriptтин алгачкы күндөрүндө код блокторунда лексикалык чөйрө болгон эмес. Демек, өткөндүн калдыктары деп айтсак болот .ifforvar

"var" кайра жарыяланышы мүмкүн

Эгер сиз бир эле өзгөрмөнү код блогунда эки жолу жарыяласаңыз let, ката пайда болот:

@A@let user;
let user; // SyntaxError: 'user' has already been declared@A@

Колдонуу менен var, сиз өзгөрмөнү каалаганча кайра жарыялай аласыз. Кайталануулар varэтибарга алынбайт:

@A@var user = "Pete";

var user; // ничего не делает, переменная объявлена раньше
// ...нет ошибки

alert(user); // Pete@A@

Эгер сиз кошумча маани берсеңиз, анда өзгөрмө жаңы мааниге ээ болот:

 
 
@A@var user = "Pete";

var user = "John";

alert(user); // John@A@

"var" функциянын башталышында иштетилет

Өзгөрмө декларациялары varфункциянын аткарылышынын башталышында иштетилет (же өзгөрмө глобалдуу болсо, сценарийдин аткарылышы).

Башкача айтканда, өзгөрмөлөр varфункциянын аткарылышынын эң башынан эле жарыяланды деп эсептелет, алардын декларациялары функциянын кайсы жеринде иш жүзүндө жайгашканына карабастан (эгерде алар уяланган функцияда болбосо).

Ошол. бул код:

@A@function sayHi() {
  phrase = "Привет";

  alert(phrase);

  var phrase;
}
sayHi();@A@

...Техникалык жактан ал төмөндөгүгө толугу менен барабар (өзгөрмө декларациясы var phraseфункциянын башына жылдырылды):

@A@function sayHi() {
  var phrase;

  phrase = "Привет";

  alert(phrase);
}
sayHi();@A@

...Ал тургай, төмөндөгү код (эстеңиз, блоктун масштабы этибарга алынбайт):

@A@function sayHi() {
  phrase = "Привет"; // (*)

  if (false) {
    var phrase;
  }

  alert(phrase);
}
sayHi();@A@

Бул жүрүм-турум "көтөрүү" (көтөрүү, көтөрүү) деп аталат, анткени бардык өзгөрмө декларациялары varфункциянын эң жогору жагына "сүзөт".

Жогорудагы мисалда if (false)шарт эч качан аткарылбайт. var phraseБирок бул эч кандай жол менен анын ичиндеги өзгөрмөнүн түзүлүшүнө тоскоол болбойт , анткени декларациялар varфункциянын башына чейин "сүзөт". Ошол. (*)өзгөрмө маани берилген учурда мурунтан эле бар.

Өзгөрмө декларациялары калкып чыгат, бирок баалуулуктарды дайындоо жок.

Муну мисал менен көрсөтүү эң оңой:

@A@function sayHi() {
  alert(phrase);

  var phrase = "Привет";
}

sayHi();@A@

линия var phrase = "Привет"эки иш-аракеттен турат:

  1. Өзгөрмө декларациясыvar
  2. Өзгөрмөгө маани ыйгаруу =.

Өзгөрмө декларациясы функциянын аткарылышынын башталышында иштетилет («калкып чыгат»), бирок маанини дайындоо ар дайым ал көрсөтүлгөн жерде коддун сабында пайда болот. Ошол. код төмөнкүдөй аткарылат:

@A@function sayHi() {
  var phrase; // объявление переменной срабатывает вначале...

  alert(phrase); // undefined

  phrase = "Привет"; // ...присвоение - в момент, когда исполнится данная строка кода.
}

sayHi();@A@

Бардык өзгөрмө декларациялары varфункциянын башында иштетилгендиктен, биз аларга каалаган жерден кайрыла алабыз. undefinedБирок, өзгөрмөлөр маани дайындалган сапка чейинки мааниге ээ .

Жогорудагы эки мисалда чалуу alertкатасыз уланды, анткени өзгөрмө phraseмурунтан эле бар болчу. Бирок анын баасы али дайындала элек, ошондуктан алдык undefined.

Бардыгы

var2 негизги айырмачылыктар бар let/const:

  1. Өзгөрмөлөрдүн varблоктук чөйрөсү жок, алар жок дегенде функциянын корпусу менен чектелет.
  2. Өзгөрмөлөрдү жарыялоо (инициализациялоо) varфункциянын аткарылышынын башталышында (же глобалдык өзгөрмөлөр үчүн сценарий) жүргүзүлөт.

Глобалдык объектке байланыштуу дагы бир кичинекей айырма бар, аны биз кийинки бөлүмдө карайбыз.

Бул өзгөчөлүктөр адатта кодго жакшы таасир этпейт. Блок аймагы ыңгайлуу. Ошондуктан, көп жылдар мурун letжана constстандартка киргизилген жана азыр өзгөрмөлөрдү жарыялоонун негизги жолу болуп саналат.