Новые функции ES6

ECMAScript 6

Переменная

(1) const и let и var

1. Разница между тремя

  • 1. Вариативное продвижение
  1. Объявление var обрабатывается так, как если бы оно было объявлено в самом начале функции, независимо от того, где оно объявлено.
  2. объявления let и const не поднимаются
  • 2. Объем
  1. var — это область действия функции, которая работает внутри функции, но будет продвигаться в {}
  2. let и const являются блочными областями, а область формируется в {}
  • 3. Повторные заявления
  1. Определение VAR может быть повторено
  2. let и const не могут быть определены повторно, иначе будет сообщено об ошибке
  • 4. константы const не могут быть изменены
  1. Переменная, объявленная const, будет считаться константой, что означает, что ее значение не может быть изменено после того, как оно установлено;
  • 5. Если const является объектом, значение, содержащееся в объекте, может быть изменено. Абстрактно говоря, адрес, на который указывает объект, не меняется:
const student = { name: 'cc' }
student.name = 'yy';// 不报错
student  = { name: 'yy' };// 报错

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

var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}
  • В приведенном выше коде есть глобальные переменныеtmp, но в области блокаletобъявляет локальную переменнуюtmp, заставляя последний связывать эту область блока, поэтому вletПрежде чем объявить переменную, правильноtmpПрисвоение выдаст ошибку.

Следует отметить несколько моментов:

# let 关键词声明的变量不具备变量提升(hoisting)特性
# let 和 const 声明只在最靠近的一个块中(花括号内)有效
# 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
# const 在声明时必须被赋值

3. Рекомендации

В повседневной разработке я предлагаю полностью использовать let/const, общие объявления переменных использовать ключевое слово let, а при объявлении некоторых элементов конфигурации (таких как адреса интерфейсов, зависимости npm, страницы по умолчанию пейджера и т. д.) переменные, которые не будут меняться) , вы можете использовать const, чтобы явно сообщить другим разработчикам проекта, что эта переменная не может быть изменена Дефекты ключевого слова var (поднятие переменной, загрязнение глобальных переменных и т. д.), чтобы можно было лучше использовать новый синтаксис

функция

(1) Стрелочные функции (стрелочные функции)

  • В ES6 стрелочная функция — это сокращенная форма функции, которая использует круглые скобки для переноса параметров, за которыми следует =>, за которым следует тело функции;

1. Стрелочные функции имеют следующие отличия от функций, созданных с помощью ключевого слова function:

  1. Стрелочные функции не имеют аргументов (предпочитают лучший синтаксис, вместо этого оператор rest)
  2. Стрелочные функции не имеют свойства прототипа и не могут использоваться в качестве конструкторов (не могут вызываться с ключевым словом new).
  3. У стрелочной функции нет собственного this, это лексическое значение, и оно ссылается на this контекста, то есть, когда вы пишете эту строку кода, this стрелочной функции уже привязано к this внешнего исполнения. контекст (лично я думаю, что это не означает, что он полностью статичен, потому что внешний контекст по-прежнему динамичен и может быть изменен с помощью call, apply и bind. Это просто показывает, что this стрелочной функции всегда равно this в верхнем контексте)

2. Три наиболее интуитивно понятных функции стрелочных функций

# 不需要 function 关键字来创建函数
# 省略 return 关键字
# 继承当前上下文的 this 关键字
  • Подробности: Когда ваша функция имеет один и только один параметр, вы можете опустить круглые скобки. Когда ваша функция возвращает только одно выражение, вы можете опустить {} и вернуться;

3. Правила

  1. Стрелочные функции, использующие оператор блока, не возвращают значение автоматически, вам нужно использовать оператор return, чтобы вернуть желаемое значение.
  2. Нельзя использовать в качестве конструктора, то есть нельзя использовать ключевое слово new для создания экземпляра объекта, иначе будет выдана ошибка.
  3. Вы не можете использовать объект arguments, не говоря уже о доступе к входящим параметрам через объект arguments, которого нет в теле функции. Если вы хотите использовать его, вы можете вместо этого использовать остальные параметры.
  4. Команду yield нельзя использовать, поэтому стрелочные функции нельзя использовать в качестве функций-генераторов.
  5. То, что возвращается, является объектом, вам нужно добавить скобку снаружи var getTempItem = id = > ({id: id,});

(2) Значение параметра функции по умолчанию

// ES6之前,当未传入参数时,text = 'default';
function printText(text) {
    text = text || 'default';
    console.log(text);
}
// ES6;
function printText(text = 'default') {
    console.log(text);
}
printText('hello'); // hello
printText();// default

(3) Обещание (обычно используется)

Как новая концепция, представленная в ES6, промисы изменили асинхронное программирование JS. Большинство асинхронных запросов в современном интерфейсе реализованы с использованием промисов. Выборка веб-API также основана на промисах. Нет необходимости кратко описывать предыдущее правило асинхронного программирования JS Функция обратного вызова, каковы недостатки функции обратного вызова и как Promise устраняет эти недостатки

Недостатки callback-функций

  1. Множественное вложение, приводящее к аду обратного вызова
  2. Прыжки кода, а не то, как люди привыкли думать
  3. Проблема доверия: вы не можете полностью доверять своему обратному вызову сторонней библиотеке, потому что вы не знаете, как сторонняя библиотека будет выполнять обратный вызов (многократное выполнение)
  4. Сторонние библиотеки могут не обеспечивать обработку ошибок
  5. Непонятно, все ли колбэки вызываются асинхронно (можно вызывать ajax синхронно, весь поток будет заблокирован до получения ответа, и он попадет в состояние suspend, что крайне не рекомендуется)

Promise

Ввиду недостатков callback-функций в ES6 была введена новая концепция Promise.Promise — это функция-конструктор.Создайте экземпляр Promise с помощью нового ключевого слова и посмотрите, как Promise решает эти проблемы callback-функций.

  1. Непонятно, все ли колбэки вызываются асинхронно (можно вызывать ajax синхронно, весь поток будет заблокирован до получения ответа, и он попадет в состояние suspend, что крайне не рекомендуется)
  • Promise предназначен для обеспечения того, чтобы все обратные вызовы обработки ответов вызывались асинхронно и не блокировали выполнение кода. Promise помещает обратный вызов метода then в очередь с именем MicroTask, чтобы гарантировать, что эти задачи обратного вызова являются синхронными задачами. После выполнения выполните его еще раз. Эта часть также является точкой знаний о цикле событий. Заинтересованные друзья могут изучить его подробно.

предложение

  • В повседневной разработке рекомендуется полностью использовать новый синтаксис промисов, поскольку асинхронное программирование в основном использует промисы.
  • Рекомендуется использовать async/await ES7 для дальнейшей оптимизации метода написания Promise.Асинхронная функция всегда возвращает промис, а await может реализовывать функцию ожидания.Async/await стал окончательным решением для асинхронного программирования, то есть , записывая асинхронный код в виде синхронизирующего кода, и может более элегантно реализовывать последовательное выполнение асинхронного кода и предоставлять более точную информацию об ошибке при возникновении асинхронной ошибки.

нить

(1) Шаблон строки

  • Когда вам нужно объединить строки, старайтесь как можно чаще использовать шаблонные строки:
// bad
const foo = 'this is a' + example;

// good
const foo = `this is a ${example}`;
  • И для ЕС6
    • Базовое форматирование строк. Встраивает выражения в строки для конкатенации. Используйте ${} для определения;
    • Обратные кавычки ES6 (``) получают это напрямую;

множество

for... цикла

  • for ... of — это новый метод обхода в ES6, который позволяет проходить структуру данных, содержащую интерфейс итератора, и возвращать значение каждого элемента Отличие от for ... in в ES3 заключается в следующем.
  1. for... of можно использовать только для итерируемых объектов, чтобы получить значение, возвращаемое итератором, for... in можно получить имена ключей всех объектов
  2. for... in будет проходить всю цепочку прототипов объекта, производительность очень низкая и не рекомендуется, а for... of только проходит текущий объект и не пересекает его цепочку прототипов
  3. Для обхода массива for... in возвращает все перечисляемые свойства в массиве (включая перечисляемые свойства в цепочке прототипов), for... of возвращает только значение атрибута, соответствующее индексу массива.
  • Принцип цикла for...of фактически использует интерфейс итератора, развернутый внутри итерируемого объекта.Если цикл for...of разложить на самый примитивный цикл for, внутренний механизм реализации можно понять таким образом

  • Можно видеть, что пока выполняется второе условие (iterator.next() существует, а res.done имеет значение true), цикл может продолжаться, и каждый раз, когда объект, сгенерированный методом next итератора, присваивается res, и затем присваивается значение res Атрибут присваивается переменной, объявленной в первом условии for ... of, а атрибут done of res контролирует, следует ли продолжать обход

3. Цикл for...of также поддерживает разрыв, продолжение, возврат (если вызывается в функции) и может использоваться с присваиванием деструктуризации объекта.

  • Массив arr возвращает объект ({a:1},{a:2},{a:3}) каждый раз, когда он использует цикл for...of, а затем деконструирует объект, находит значение атрибута a , и присваивает его obj.a, так что obj.a будет присвоено 1, 2, 3 в каждом раунде цикла соответственно

объект

(1) Аббревиатура свойства/метода объекта (обычно используется)

1. es6 позволяет опускать имя свойства, когда свойство и значение объекта совпадают

  • должен знать об этом **
    • Имя свойства опущено вместо значения
    • значение должно быть переменной

2. Сокращение свойства объекта часто используется с деструктурирующим присваиванием.

  • В сочетании с присваиванием деструктурирования выше код здесь фактически объявит переменные x, y и z, потому что функция bar вернет объект с тремя свойствами x, y и z, а присваивание деструктурирования будет искать правильный сторона знака равенства Находятся свойства x, y, z выражения и присваиваются объявленным переменным x, y, z

3. Сокращение метода

  • es6 позволяет, когда значение свойства объекта является функцией (то есть методом), вы можете использовать сокращенную форму

Модульный модуль (обычно используется)

До появления модуля ES6 модуляризация всегда была в центре внимания разработчиков интерфейсов.Ввиду растущего спроса и количества кода необходимо решение, позволяющее разделить раздутый код на небольшие модули, тем самым запустив AMD, CMD и The три модульных решения CommonJs, первое используется на стороне браузера, а последние два используются на стороне сервера, пока не появится модуль ES6.

  • Модуль ES6 в настоящее время не поддерживается браузерами по умолчанию. Необходимо использовать Babel. Эта ошибка часто отображается при ежедневном написании демо.

Возможности модуля

  1. Модуль ES6 является статическим, что означает, что он запускается на этапе компиляции и имеет тот же эффект подъема, что и var и функция (эта функция позволяет ему поддерживать встряхивание дерева)
  2. Автоматически принимает строгий режим (это возвращает undefined на верхнем уровне)
  3. Модуль ES6 поддерживает использование экспорта {} для экспорта именованных интерфейсов или экспорта по умолчанию для экспорта анонимных интерфейсов.

Опыт: ES6 поддерживает не только экспорт переменных, но и экспорт констант. export const sqrt = Math.sqrt;//Экспорт константы

Вывод: оператор импорта может одновременно импортировать функции по умолчанию и другие переменные. импортировать метод по умолчанию {otherMethod} из 'xxx.js';

экспорт модуля.js

импорт импорт

  • Разница между ними заключается в том, что экспорт {} экспортирует ссылку на переменную, а экспорт по умолчанию экспортирует значение.
  • Что это значит, то есть, то есть после использования импорта в a.js, в Module.js изменяется в Module.js, он будет немедленно отражено на a.js и module.js после изменения переменной y, y или Оригинальное значение в a.js

Некоторые различия между модулем ES6 и CommonJs

  1. CommonJs выводит копию значения, модуль ES6 выводит ссылку на переменную через экспорт {}, а экспорт по умолчанию выводит значение
  2. CommonJs запускается на сервере и предназначен для загрузки во время выполнения, то есть код возвращается для загрузки модуля до тех пор, пока эта строка не будет выполнена, в то время как модуль ES6 представляет собой статический вывод интерфейса, который происходит на этапе компиляции.
  3. CommonJs запускается один раз и генерирует кеш при первой загрузке, после загрузки возвращается все содержимое кеша.

импорт() динамическая загрузка

  • Что касается характеристик статической компиляции модуля ES6, то ее нельзя загружать динамически, но всегда будут какие-то требования для динамической загрузки модулей, поэтому сейчас есть предложение использовать import как функцию для динамической загрузки модулей, которая возвращает Promise, когда обещание разрешено, значение - выходной модуль

  • Метод записи ES6 с отложенной загрузкой роутинга в Vue использует эту технологию, так что компоненты могут динамически загружаться для рендеринга представлений при переключении роутинга.

присваивание деструктуризации

понимать

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

  • деструктурирующий массив
var arr = [1, 2, 3, 4];
let [a, b, c, d] = arr;
console.log(a); // 1
console.log(b); // 2
  • Разрушение объектов
var luke = { occupation: 'jedi', father: 'anakin' };
let {occupation, father} = luke;
console.log(occupation); // jedi
console.log(father); // anakin
  • vuex использует деструктурирование объектов

предложение

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

Оператор rest Оператор rest/spread (обычно используется)

Оператор rest/spread также является очень важным синтаксисом в ES6, используя 3 точки (...), за которыми следует структура данных с интерфейсом итератора.

спред оператор

  • Взяв в качестве примера массив, использование оператора спреда позволяет «расширить» массив, можно понять, что массив — это контейнер для хранения набора элементов, а оператор спреда можно использовать для дизассемблирования контейнера, чтобы осталась только коллекция элементов.Вы можете поместить эти коллекции элементов в другой массив вместо метода concat прототипа массива в ES3

оператор остатка

Одной из наиболее важных особенностей оператора остатка является то, что он заменяет предыдущие аргументы.

rest - это просто формальный параметр, вы можете назвать его по желанию

  • Доступ к объекту arguments функции — очень затратная операция, предыдущие arguments.callee и arguments.caller упразднены, рекомендуется не использовать объект arguments в среде, поддерживающей синтаксис ES6, а вместо этого использовать оставшийся оператор ( стрелочные функции не имеют аргументов, для доступа к набору параметров необходимо использовать оператор rest)

  • Оператор остатка можно использовать с деструктурирующим присваиванием массива, но он должен быть помещен в конец, потому что принцип остатка оператора фактически заключается в использовании итератора массива, он будет потреблять все итераторы массива после 3 балла, чтение Все итераторы генерируют атрибут value объекта, и после оставшегося оператора не может быть деструктурирующего присваивания, потому что оставшийся оператор уже израсходовал все итераторы, а деструктурирующее присваивание массива также потребляет итераторы, но нет итераторы в это время, поэтому сообщит об ошибке

  • Здесь сначала будет использоваться итератор массива справа, ...arr будет потребляться все оставшиеся итераторы, а во втором примере ...arr будет напрямую потреблять все итераторы, в результате чего не будет итераторов для последнего использования, поэтому будет отчет ошибка, потому что это бессмысленная операция

разница

Разница между оператором остатка и оператором спреда заключается в том, что оператор остатка собирает эти наборы и помещает их в массив справа, а оператор спреда разбивает массив справа на наборы элементов, которые являются противоположными.

Использование оператора распространения с объектами

  • Это синтаксис ES9.ES9 поддерживает использование операторов распространения в объектах.Я говорил ранее, что принцип операторов распространения для массивов состоит в том, чтобы потреблять все итераторы, но в объектах нет итераторов.Я лично думаю, что принцип реализации может быть другим, но его все равно можно понимать как отделение пары ключ-значение от объекта, его можно поместить в другой обычный объект

  • По сути, он похож на другой новый API ES6, а именно на Object.assign.Они могут объединять объекты, но все же есть некоторые отличия.Object.assign вызовет функцию setter целевого объекта, в то время как оператор распространения объекта не будет

предложение

  • Используйте оператор распространения, чтобы быстро преобразовать массив, подобный массиву, в реальный массив.
  • Объединить несколько массивов

функция курирования

класс (ES6)

Разработчики, знакомые с чистыми объектно-ориентированными языками, такими как Java, object-c, c# и т. д., будут иметь особое чувство класса. В ES6 появились классы, чтобы сделать объектно-ориентированное программирование на JavaScript проще и понятнее.

class Animal {
    // 构造函数,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数.
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString 是原型对象上的属性
    toString() {
      console.log('name:' + this.name + ',color:' + this.color);

    }
  }

 var animal = new Animal('dog','white');//实例化Animal
 animal.toString();

 console.log(animal.hasOwnProperty('name')); //true
 console.log(animal.hasOwnProperty('toString')); // false
 console.log(animal.__proto__.hasOwnProperty('toString')); // true

 class Cat extends Animal {
  constructor(action) {
    // 子类必须要在constructor中指定super 函数,否则在新建实例的时候会报错.
    // 如果没有置顶consructor,默认带super函数的constructor将会被添加、
    super('cat','white');
    this.action = action;
  }
  toString() {
    console.log(super.toString());
  }
 }

 var cat = new Cat('catch')
 cat.toString();

 // 实例cat 是 Cat 和 Animal 的实例,和Es5完全一致。
 console.log(cat instanceof Cat); // true
 console.log(cat instanceof Animal); // true

includes

Функция include() используется для определения того, содержит ли массив указанное значение, и возвращает true, если да, и false в противном случае.

Функция include очень похожа на функцию indexOf, следующие два выражения эквивалентны:

arr.includes(x)
arr.indexOf(x) >= 0

Далее определим, содержит ли число элемент:

Потренируйтесь перед ES7

Используйте indexOf(), чтобы проверить, существует ли элемент в массиве.На данный момент вам нужно определить, равно ли возвращаемое значение -1:

let arr = ['react', 'angular', 'vue'];

if (arr.indexOf('react') !== -1)
{
    console.log('react存在');
}

Используйте ES7 include()

Используйте include(), чтобы проверить, существует ли элемент в массиве, что более интуитивно понятно и просто:

let arr = ['react', 'angular', 'vue'];

if (arr.includes('react'))
{
    console.log('react存在');
}

Экспоненциальный оператор

Оператор экспоненты был введен в ES7.**,**с участиемMath.pow(..)Эквивалентный результат расчета.

Не используйте оператор экспоненты

Используйте пользовательскую рекурсивную функцию calculateExponent или Math.pow() для выполнения экспоненциальных операций:

function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1);
    }
}

console.log(calculateExponent(2, 10)); // 输出1024
console.log(Math.pow(2, 10)); // 输出1024

Используйте экспоненциальный оператор

Используйте оператор экспоненты **, точно так же, как операторы +, - и т. д.:

console.log(2**10);// 输出1024

1