ES6 --- Понимание позволит не наступать на ямы

внешний интерфейс JavaScript опрос

Давай поболтаем! (Первые несколько больших парней могут автоматически игнорировать это)

Прежде всего, шлепните мое невежество!

Когда я впервые столкнулся с ES6, я «подумал», что понял пусть. Затем в долгий путь самообучения,letСнова и снова я осознавал свое невежество.

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


первое знакомство пусть

Как и многие люди, услышав, что ES6 очень полезен, я продолжал изучать этот материал, полный синтаксического сахара. Я начал переходить к учебнику для новичков с идеей быстро пройти es6 с помощью emmmm (потому что я думаю, что урок здесь очень простой, но я надеюсь, что в будущем все будут тщательно выбирать учебник для новичков!!!)

Как показано на рисунке, это мое первоначальное понимание его — решение проблемы отсутствия в javascript области видимости на уровне блоков. Ну.... вот и все.

Давайте объясним

"1" Область действия переменных, объявленных let, является блочной;

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

Использование похоже на var, но объявленная переменная действительна только в пределах блока кода, где находится команда let.

Давайте поговорим о яме в этой «области блочного уровня»! ! !

В первую очередь я сказал первую яму на примере Руана Дашена

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); 

Каков результат? Это 6?ответ10

Зачем? Поскольку в приведенном выше коде переменная i объявлена ​​командой var и действительна в глобальной области видимости, поэтому глобально существует только одна переменная i. Значение переменной i будет меняться каждый раз, когда цикл зацикливается, а console.log(i) внутри функции, назначенной массиву a в цикле, i в нем указывает на глобальный i. Другими словами, i во всех элементах массива a указывает на одно и то же i, что приводит к тому, что на выходе среды выполнения будет значение i в последнем раунде, равное 10.

Итак, как решить эту проблему? Решение до ES6 — построение замыканий для формирования неразрушаемых областей видимости для сохранения переменных.

var a = [];
for (var i = 0; i < 10; i++) {
  (function (arg) {a[i] = function () {
    console.log(arg);
  }})(i);
}
a[6](); //6

Решение ES6

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

В коде переменная i объявлена ​​с помощью let, а текущая i действительна только в этом цикле, поэтому i каждого цикла на самом деле является новой переменной, поэтому окончательный вывод равен 6.Вот как это описано в коде ES5!

"use strict";

var a = [];

var _loop = function _loop(i) {
  a[i] = function () {
    console.log(i);
  };
};

for (var i = 0; i < 10; i++) {
  _loop(i);
}
a[6](); // 6

Часто встречается другой общий кодовый код, и часто встречаются интервью.

var liList = document.querySelectorAll('li') // 共5个li
for( var i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

Сколько печатать? 0, 1, 2, 3, 4 или 5, 5, 5, 5, 5? Я считаю, что каждый должен знать, что нажатие li в свою очередь напечатает 5 5s.

Если вы измените var i на let i, он напечатает 0, 1, 2, 3, 4 соответственно:

var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

Пожалуйста, объясните мое понимание!

  • Между скобками for( let i = 0; i
  • for( let i = 0; i
  • Вот как это описано в коде ES5!
'use strict';

var liList = document.querySelectorAll('li'); // 共5个li

var _loop = function _loop(i) {
  liList[i].onclick = function () {
    console.log(i);
  };
};

for (var i = 0; i < liList.length; i++) {
  _loop(i);
}

Резюме: Надеюсь, вы будете уделять больше внимания, когда столкнетесь с такими проблемами, как циклические асинхронные события, и не попадете в яму☺

"2" Переменная, объявленная командой let, не имеет продвижения, и существует временная мертвая зона;

Давайте сначала объясним эти два.

переменное продвижение

console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError

var foo = 2;
let bar = 2;

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

Временная мертвая зона

let x = 'global'
{
  console.log(x) // Uncaught ReferenceError: x is not defined
  let x = 1
}

Имеется глобальная переменная x, но let объявляет локальную переменную x в блочной области видимости, из-за чего последняя связывает блочную область видимости, поэтому перед тем, как let объявит переменную, присваивание tmp сообщит об ошибке.

Прежде чем подробно объяснять эту проблему, давайте сначала разберемся с предварительной интерпретацией переменных в нашей области до ES6.

var a = 1;
function b(params) {
    var c = 2; 
    console.log(params);
}

console.log(a);
b(3);

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

b(3);
function b(params) {
    var c = 2; 
    console.log(params);
}

Тогда это второй шаг выполнения функции.

Достаточно ясно! ! ! ! Достаточно ясно! ! !

После того, как мы разберемся с этим, скажем, давайте еще раз.Тогда вы, естественно, поймете вышеперечисленные проблемы.

Это о том, чтобы

Найдите все переменные, объявленные с помощью let, и «создайте» эти переменные в среде.

Начать выполнение кода (обратите внимание, что он не был инициализирован или не притворялся неопределенным)

Когда переменная, объявленная с помощью let, выполняется, переменная "инициализируется и назначается напрямую"

Теперь о вышеупомянутом несуществующем продвижении переменных, вы должны понимать, что существует временная мертвая зона. Временная мертвая зона создается из-за того, что переменные, объявленные с помощью let, имеют область действия на уровне блоков и нет продвижения переменных.

Давайте также посмотрим, как выглядела временная мертвая зона в среде до es6.

//es6中
let x = 'global'
{
  console.log(x) // Uncaught ReferenceError: x is not defined
  let x = 1
}

//之前版本的环境中
'use strict';

var x = 'global';
{
  console.log(_x); // Uncaught ReferenceError: x is not defined
  var _x = 1;
}

《3》let не может повторять объявление существующей переменной

Эта точка знаний, по сути, не яма, просто обратите на нее внимание.

// 报错
function () {
  let a = 10;
  var a = 1;
}

// 报错
function () {
  let a = 10;
  let a = 1;
}

Суммировать

Таким образом, в общей сложности три очка знаний: полностью понять еще придется использовать! ! !

1, пусть область блочного уровня!

2. Нет продвижения переменных для переменных, объявленных let, и есть временная мёртвая зона!

3. Переменные, объявленные с помощью let, нельзя объявлять повторно, независимо от того, неоднократно ли вы используете var или другие объявления!

Это конец нашей истории на данный момент (сумасшедшие умолять большого босса взять меня с собой) Прежде чем вы это узнаете, уже 10 часов вечера, и пора возвращаться в общежитие хахаха Если вы учись, будь осторожен хахаха