Основные функции ES6

JavaScript Promise Webpack Babel

предисловие

Хотя ES6 предоставляет много новых возможностей, мы не часто используем его в нашей реальной работе.Согласно правилу 28, мы должны тратить 80% нашей энергии и времени на 20% ядра.Функции, вы получите чудодейственный эффект с половина усилий! Писать статьи непросто, поддержите и обратите внимание!Начальный адрес этой статьиБлог GitHub (с картой ума)

1. Конфигурация среды разработки

В этом разделе выделяются:Babel компилирует синтаксис ES6, как использовать webpack для достижения модульности.

1.babel

Зачем тебе Бабель?

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

export各个浏览器兼容性一览表

Как видно из приведенного выше рисунка, некоторые браузеры не очень дружат с ES6.Для совместимости с ES6 многие команды разработали различные инструменты синтаксического анализа и преобразования (такие как babel, jsx, traceur и т. д.), которые может быть написан нами Преобразование грамматики ES6 в ES5 эквивалентно работе переводчиком между ES6 и браузером. вBabel— это широко используемый транскодер, который может преобразовывать код ES6 в код ES5 для выполнения в существующих средах.

Как настроить бабель?

·首先要先安装node.js,运行npm init,然后会生成package.json文件
·npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest
·创建并配置.babelrc文件//存放在项目的根目录下,与node_modules同级
·npm install -g babel-cli
·babel-version

Файл конфигурации Babel — .babelrc, который хранится в корневом каталоге проекта. Этот файл используется для установки правил транскодирования и плагинов. Детали следующие:

//.babelrc文件
{
    "presets": ["es2015", "latest"],
    "plugins": []
}

Убедитесь, что конфигурация прошла успешно

·创建./src/index.js
·内容:[1,2,3].map(item=>item+1);
·运行babel./src/index.js

После запуска вы получите следующую часть, указывающую на то, что babel успешно настроен.

"use strict";
[1, 2, 3].map(function (item) {
  return item + 1;
});

2.webpack

Зачем использовать WebPack?

Многие из сегодняшних веб-страниц на самом деле можно рассматривать как многофункциональные приложения.Они имеют сложный код JavaScript и множество пакетов зависимостей.Со временем появились инструменты модуляризации.Среди них, webpack является мощным и глубоко любимым людьми.Webpack работает следующим образом: возьмите свой проект в целом, через заданный основной файл (например, index.js), Webpack начнет с этого файла, чтобы найти все зависимые файлы вашего проекта, использовать загрузчики для их обработки и, наконец, Упакован как один (или несколько) распознаваемых браузером файлов JavaScript.

Как настроить вебпак?

·npm install webpack babel-loader --save-dev
·创建并配置 webpack.config.js//webpack.config.js文件与package.json同级
·配置 package.json中的scripts
·运行 npm start
//配置 webpack.config.js  针对.js结尾的文件除了node_modules都用babel解析
module.exports = {
    entry: './src/index.js',
    output: {
        path: __dirname,
        filename: './build/bundle.js'
    },
    module: {
        rules: [{
            test: /\.js?$/,
            exclude: /(node_modules)/,
            loader: 'babel-loader'
        }]
    }
}
//配置 package.json中的scripts
"scripts": {
    "start": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  }

2. Область действия на уровне блоков

ES5 имеет только глобальную область видимости и область видимости функции (например, нам приходится оборачивать код внутри функций, чтобы ограничить область действия), что приводит к множеству проблем:

Случай 1: внутренняя переменная переопределяет внешнюю переменную

var tmp = new Date();
function f() {
  console.log(tmp); //undefined
  if (false) {   
    var tmp = "hello world";
  }
}

Случай 2: переменная просачивается и становится глобальной переменной

var s = 'hello';
for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}
console.log(i); // 5

ES6 предоставляет let и const вместо var для объявления переменных, а новое объявление поддерживает область видимости на уровне блоков с помощью фигурных скобок, что дает некоторые преимущества:

1. Немедленно выполняемые функциональные выражения (IIFE) больше не требуются.В ES5 нам нужно создать немедленно выполняемое функциональное выражение, чтобы гарантировать, что мы не загрязняем глобальную область видимости. В ES6 мы можем использовать более простые фигурные скобки ({}), а затем использовать const или let вместо var для достижения того же эффекта.

2. Замыкания в телах циклов больше не проблематичныВ ES5, если в теле цикла есть замыкание и доступ к переменным вне замыкания вызовет проблемы. В ES6 вы можете использовать «let», чтобы избежать проблем.

3. Предотвратить повторное объявление переменныхES6 не позволяет повторно объявлять переменные с одним и тем же именем с помощью let или const в одной и той же области видимости. Это очень полезно для предотвращения дублирования объявлений функциональных выражений в разных js-библиотеках.

В-третьих, расширение массива

1. Array.from() : преобразовать объект псевдомассива или проходимый объект в настоящий массив.

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

...
<button>测试1</button>
<br>
<button>测试2</button>
<br>
<button>测试3</button>
<br>
<script type="text/javascript">
let btns = document.getElementsByTagName("button")
console.log("btns",btns);//得到一个伪数组
btns.forEach(item=>console.log(item)) Uncaught TypeError: btns.forEach is not a function
</script>

Для псевдомассивов не существует общего метода для массивов, и прямой обход вызовет ошибки.ES6 добавляет метод Array.from(), чтобы обеспечить четкий и понятный способ решения этой проблемы.

Array.from(btns).forEach(item=>console.log(item))将伪数组转换为数组

2.Array.of(v1, v2, v3): преобразовать ряд значений в массив

При вызове конструктора new Array(), в зависимости от типа и количества переданных аргументов, он на самом деле приводит к различным результатам, например:

let items = new Array(2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // undefined
console.log(items[1]) ;
let items = new Array(1, 2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // 1
console.log(items[1]) ; // 2

Когда конструктор Array вызывается с одним числовым параметром, свойство length массива устанавливается равным этому параметру. При вызове с несколькими аргументами (числовыми или нет) эти аргументы также становятся элементами целевого массива. Такое поведение массивов сбивает с толку и рискованно, потому что иногда о типе передаваемого параметра можно не заботиться.

В ES6 появился метод Array.of() для решения этой проблемы. Этот метод очень похож на конструктор Array, но не дает особых результатов при использовании одного числового параметра.Метод Array.of() всегда создает массив всех входящих аргументов, независимо от количества и типа аргументов.:

let items = Array.of(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2
items = Array.of(2);
console.log(items.length); // 1
console.log(items[0]); // 2

Array.of в основном может использоваться для замены Array() или newArray(), и нет перегрузки из-за разных параметров, и их поведение очень единообразно.

3. find() и findIndex() для экземпляров массива

Метод find экземпляра массива используется для поиска первого подходящего члена массива. Его параметр является функцией обратного вызова, и все элементы массива выполняют функцию обратного вызова по очереди, пока не будет найден первый элемент, возвращаемое значение которого равно true, а затем этот элемент возвращается. Возвращает неопределенное значение, если нет подходящих членов.

[1, 4, -5, 10].find((n) => n < 0) // -5

Использование метода findIndex экземпляра массива очень похоже на метод find, который возвращает позицию первого подходящего члена массива или -1, если все члены не подходят.

[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

4. Экземпляр массива включает()

Метод Array.prototype.includes возвращает логическое значение, указывающее, содержит ли массив заданное значение. Второй параметр этого метода представляет начальную позицию поиска, которая по умолчанию равна 0. Если второй параметр отрицательный, то он указывает позицию обратного отсчета, а если он больше длины массива в это время (например, второй параметр равен -4, а длина массива равна 3), то он будет сброшен начать с 0.

[1, 2, 3].includes(2)   // true
[1, 2, 3].includes(3, -1); // true
[1, 2, 3, 5, 1].includes(1, 2); // true

До этого метода мы обычно использовали метод indexOf массива, чтобы проверить, содержит ли он определенное значение. Метод indexOf имеет два недостатка:Во-первых, он недостаточно семантичен, его смысл в том, чтобы найти первое вхождение значения параметра, поэтому не интуитивно сравнивать, не равно ли оно -1. Во-вторых, он использует оператор строгого равенства (===) внутри для оценки, что приведет к неправильной оценке NaN..

[NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true

5. entry(), keys() и values() для экземпляров массива

ES6 предоставляет entry(), keys() и values() для обхода массивов. Все они возвращают объект обходчика, который можно пройти с помощью цикла for...of Единственная разница в том, что keys() — это обход имен ключей, values() — обход значений ключей, а entry() — обход ключевых значений.

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

В-четвертых, стрелочная функция

ES6 позволяет определять функции с помощью «стрелок» (=>). У него есть две основные функции: сокращение кода и изменение этого указателя.Далее мы подробно представим:

1. Сократите код

const double1 = function(number){
   return number * 2;   //ES5写法
}
const double2 = (number) => {
 return number * 2;    //ES6写法
}
const double4 = number => number * 2; //可以进一步简化

Не забудьте добавить круглые скобки для нескольких параметров

 const double6 = (number,number2) => number + number2;

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

 const double = (number,number2) => {
   sum = number + number2 
   return sum;
 }

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

// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报
let getTempItem = id => ({ id: id, name: "Temp" });

Кроме того, есть преимущество упрощения функции обратного вызова.

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);//[1, 4, 9]

2. Измените это на точку

Объект this в языке JavaScript долгое время был головной болью, и вы должны быть очень осторожны при использовании this в методах объекта. Стрелочная функция "привязывает" это, что во многом решает эту проблему. Сначала рассмотрим пример:

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map(function(member){
      return `${member}隶属于${this.teamName}小组`;    // this不知道该指向谁了
    })
  }
}
console.log(team.teamSummary());//["Henry隶属于undefined小组", "Elyse隶属于undefined小组"]

В функцию teamSummary встроена еще одна функция, которая приводит к внутренней путанице this.Как его изменить:

Способ 1, пусть self = this

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    let self = this;
    return this.members.map(function(member){
      return `${member}隶属于${self.teamName}小组`;
    })
  }
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]

Способ 2, функция привязки

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map(function(member){
      // this不知道该指向谁了
      return `${member}隶属于${this.teamName}小组`;
    }.bind(this))
  }
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]

Способ третий, стрелочная функция

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map((member) => {
      // this指向的就是team对象
      return `${member}隶属于${this.teamName}小组`;
    })
  }
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]

3. Примечания по использованию

(1) Объект this в теле функции — это объект, в котором он определен, а не объект, в котором он используется.

(2) Его нельзя использовать как конструктор, то есть нельзя использовать новую команду, иначе будет выброшена ошибка.

(3) Вы не можете использовать объект arguments, которого нет в теле функции. Если вы хотите использовать его, вы можете вместо этого использовать остальные параметры.

(4) Команду yield нельзя использовать, поэтому стрелочные функции нельзя использовать в качестве функций генератора.

Пять, остальные параметры

В ES6 введены остальные параметры (в виде... имени переменной) для получения избыточных параметров функции, поэтому нет необходимости использовать объект arguments.

Переменная в паре с остальным параметром представляет собой массив, который помещает в массив избыточные параметры.Возьмем пример: как реализовать функцию суммирования?

Традиционное письмо:

function addNumbers(a,b,c,d,e){
  var numbers = [a,b,c,d,e];
  return numbers.reduce((sum,number) => {
    return sum + number;
  },0)
 }
 console.log(addNumbers(1,2,3,4,5));//15

ES6 пишет:

 function addNumbers(...numbers){
  return numbers.reduce((sum,number) => {
    return sum + number;
  },0)
 }
 console.log(addNumbers(1,2,3,4,5));//15

Может также сочетаться с назначением деструктурирования

var array = [1,2,3,4,5,6];
var [a,b,...c] = array;
console.log(a);//1
console.log(b);//2
console.log(c);//[3, 4, 5, 6]

остальные параметры также можно комбинировать со стрелочными функциями

const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]  

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

②параметр rest нельзя использовать в установщике литерала объекта

let object = {
    set name(...value){   //报错
        //执行一些逻辑
    }
}

6. Оператор спреда

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

Когда он используется перед строкой или массивом, он называется оператором распространения.Лично его можно понимать как операцию, обратную параметру rest, которая используется для дизассемблирования массива или строки.. Иногда функции не позволяют передавать массивы, в этом случае очень удобно использовать оператор спреда, если не верите, рассмотрим пример: метод Math.max(), который принимает любое количество параметров и возвращает максимальное значение.

let value1 = 25,				
let value2 = 50;
console.log(Math.max(value1, value2));	//	50

Но если вы хотите обработать значения в массиве, как найти максимальное значение в этой точке? Метод Math.max() не позволяет передавать массив. На самом деле вы можете добавить ... к массиву, как и с остальным параметром, и передать его непосредственно в Math.max()

let values = [25,50,75,	100]
//等价于console.log(Math.max(25,50,75,100));
console.log(Math.max(...values));	//100

Оператор спреда также можно смешивать с другими параметрами.

let values = [-25,-50,-75,-100]
console.log(Math.max(...values,0));	//0

Оператор Spread деконструирует строки и массивы

var array = [1,2,3,4,5];
console.log(...array);//1 2 3 4 5
var str = "String";
console.log(...str);//S t r i n g

Также можно сращивать

var defaultColors = ["red","greed"];
var favoriteColors = ["orange","yellow"];
var fallColors = ["fire red","fall orange"];
console.log(["blue","green",...fallColors,...defaultColors,...favoriteColors]
//["blue", "green", "fire red", "fall orange", "red", "greed", "orange", "yellow"]

Семь, назначение деструктурирования -- более удобный доступ к данным

В ES6 добавлена ​​деструктуризация, то есть процесс разбиения структуры данных на более мелкие части.

1. Чем полезна деконструкция?

В ES5 и более ранних версиях получение информации из объектов или массивов и сохранение конкретных данных в локальных переменных требовало написания большого количества похожего кода. Например:

 var expense = {
   type: "es6",
   amount:"45"
 };
 var type = expense.type;
 var amount = expense.amount;
 console.log(type,amount);

Этот код извлекает значения типа и суммы объекта расходов и сохраняет их в локальных переменных с тем же именем. Хотя этот код выглядит просто, представьте, что если у вас есть большое количество переменных для обработки, вам нужно присвоить им значения одну за другой; и если у вас есть вложенная структура данных для обхода в поисках информации, вы можете копаться в ней. в целом немного структуры данных.

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

2. Объект

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

const { type,amount } = expense;
console.log(type,amount);

Давайте посмотрим на другой пример:

let node = {type:"Identifier",	name:"foo"},	
type = "Literal",name = 5;
({type,name}= node);//	使用解构来分配不同的值 
console.log(type); //	"Identifier" 
console.log(name); //	"foo"

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

По умолчанию:При необходимости можно определить значение по умолчанию, которое будет использоваться, если указанное свойство не существует. Для этого добавьте знак равенства после имени свойства и укажите значение по умолчанию, например:

let node = {
  type: "Identifier",
  name: "foo"
};
let {
  type,
  name,
  value = true
} = node;
console.log(type); //	"Identifier" 
console.log(name); //	"foo" 
console.log(value); //	true

Деструктуризация вложенных объектов:Используя синтаксис, подобный объектному литералу, вы можете углубиться во вложенные структуры объектов, чтобы извлечь нужные данные.

let node = {
  type: "Identifier",
  name: "foo",
  loc: {
    start: {
      line: 1,
      column: 1
    },
    end: {
      line: 1,
      column: 4
    }
  }
};
let { loc: { start }} = node;
console.log(start.line); //	1 
console.log(start.column); //	1

Шаблон деструктуризации в этом примере использует фигурные скобки, чтобы указать, что он должен спускаться в свойство loc объекта узла, чтобы найти свойство start.

Деструктурирование параметров, которые должны передаваться по значению

function setCookie(name, value, {
  secure,
  path,
  domain,
  expires
}) {
  //	设置cookie的代码 
}
  setCookie("type", "js");//报错

В рамках этой функции параметры имени и значения являются обязательными, а параметры secure, path, domain и expires — нет. По умолчанию вызов функции без передачи значения параметру деструктуризации вызывает ошибку. Как и в приведенном выше примере, если setCookie не передает третий параметр, будет сообщено об ошибке. Если параметр деструктуризации является необязательным, можно указать значения по умолчанию для параметра деструкции для обработки таких ошибок.

function setCookie(name, value, {
  secure,
  path,
  domain,
  expires
} = {}) {}
setCookie("type", "js");//不会报错

3. Массив

const names = ["Henry","Bucky","Emily"];
const [name1,name2,name3] = names;
console.log(name1,name2,name3);//Henry Bucky Emily
const [name,...rest] = names;//结合展开运算符
console.log(rest);//["Bucky", "Emily"]

Используйте деструктуризацию {}, чтобы вернуть количество массивов

const {length} = names;
console.log(length);//3

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

let colors = ["red", "green", "blue"],
  firstColor = "black",
  secondColor = "purple";
[firstColor, secondColor] = colors;
console.log(firstColor); //	"red" 
console.log(secondColor);	// "green"

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

let colors = ["red"];
let [firstColor, secondColor = "green"] = colors;
console.log(firstColor); //	"red" 
console.log(secondColor);//	"green"

Совпадение с остальным параметром

В ES5 метод concat() часто используется для клонирования массивов, например:

//在ES5中克隆数组 
var colors = ["red", "green", "blue"];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"

В ES6 вы можете использовать синтаксис остальных элементов для достижения того же эффекта.

//在ES6中克隆数组 
let colors = ["red", "green", "blue"];
let [...clonedColors] = colors;
console.log(clonedColors); //[red,green,blue]

Далее рассмотрим пример: как преобразовать массив в объект

const points = [
  [4,5],
  [10,1],
  [0,40]
];
//期望得到的数据格式如下,如何实现?
// [
//   {x:4,y:5},
//   {x:10,y:1},
//   {x:0,y:40}
// ]
let newPoints = points.map(pair => {
  const [x,y] = pair;
  return {x,y}
})
//还可以通过以下办法,更为简便
let newPoints = points.map(([x,y]) => {
  return {x,y}
})
console.log(newPoints);

Гибридная деконструкция

const people = [
  {name:"Henry",age:20},
  {name:"Bucky",age:25},
  {name:"Emily",age:30}
];
//es5 写法 
var age = people[0].age;
console.log(age);
//es6 解构
const [age] = people;
console.log(age);//第一次解构数组 {name:"Henry",age:20}
const [{age}] = people;//再一次解构对象
console.log(age);//20

4. Обратите внимание

Когда деструктуризация используется с var, let и const для объявления переменной, необходимо предоставить инициализатор (т. е. значение справа от знака равенства). Следующий код выдает синтаксическую ошибку из-за отсутствия инициализаторов:

var { type, name }; // 语法错误! 
let { type, name }; // 语法错误!
const { type, name }; // 语法错误!

Восемь, строка шаблона (строка шаблона)

Строки-шаблоны — это расширенные версии строк, обозначаемые обратными кавычками (`).Его можно использовать как обычную строку, его также можно использовать для определения многострочных строк или для встраивания переменных в строки. Чтобы встроить переменные и функции в строку шаблона, вам нужно написать имя переменной в ${}.

let name = "Henry";
function makeUppercase(word){
  return word.toUpperCase();
}
let template = 
  `
  <h1>${makeUppercase('Hello')}, ${name}!</h1>//可以存放函数和变量
  <p>感谢大家收看我们的视频, ES6为我们提供了很多遍历好用的方法和语法!</p>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
  `;
document.getElementById('template').innerHTML = template;

Для другого примера в работе обычно используется библиотека ElementUI, при настройке всплывающего окна очень удобно использовать шаблонную строку:

   await this.$alert(
          `<p><strong>确认是否升级${
            this.lectureName
          }</strong><br>(若已存在讲义套件,升级后请重新生成)</p>`,
          {
            dangerouslyUseHTMLString: true
          }
        )

9. В чем разница между Class и традиционными конструкторами

Концептуально в JS до ES6 не было концепции «классов», как в других объектно-ориентированных языках. Долгое время люди использовали ключевое слово new для создания объектов с помощью функций (также называемых конструкторами) в виде «классов». Поскольку JS не поддерживает нативные классы, а только имитирует через прототипы, различные методы имитации классов сильно запутывают по сравнению с традиционными объектно-ориентированными методами, особенно когда подкласс наследует родительский класс, а подкласс вызывает метод родительского класса и т. д. когда требуется. ES6 предоставляет метод записи, более близкий к традиционным языкам, и вводит понятие Class (класса) как шаблона для объектов. С помощью ключевого слова class можно определить классы.Но классы — это просто синтаксический сахар для объектно-ориентированного шаблона, основанного на прототипах..

Сравните, как классы реализованы в традиционных конструкторах и ES6:

//传统构造函数
function MathHandle(x,y){
  this.x=x;
  this.y=y;
}
MathHandle.prototype.add =function(){
  return this.x+this.y;
};
var m=new MathHandle(1,2);
console.log(m.add())
//class语法
class MathHandle {
 constructor(x,y){
  this.x=x;
  this.y=y;
}
 add(){
   return this.x+this.y;
  }
}
const m=new MathHandle(1,2);
console.log(m.add())

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

typeof MathHandle //"function"
MathHandle===MathHandle.prototype.constructor //true

Сравните, как реализовано наследование в традиционных конструкторах и ES6:

//传统构造函数继承
function Animal() {
    this.eat = function () {
        alert('Animal eat')
    }
}
function Dog() {
    this.bark = function () {
        alert('Dog bark')
    }
}
Dog.prototype = new Animal()// 绑定原型,实现继承
var hashiqi = new Dog()
hashiqi.bark()//Dog bark
hashiqi.eat()//Animal eat
//ES6继承
class Animal {
    constructor(name) {
        this.name = name
    }
    eat() {
        alert(this.name + ' eat')
    }
}
class Dog extends Animal {
    constructor(name) {
        super(name) // 有extend就必须要有super,它代表父类的构造函数,即Animal中的constructor
        this.name = name
    }
    say() {
        alert(this.name + ' say')
    }
}
const dog = new Dog('哈士奇')
dog.say()//哈士奇 say
dog.eat()//哈士奇 eat

Наследование между классами может быть достигнуто с помощью ключевого слова extends, что намного понятнее и удобнее, чем реализация наследования в ES5 путем изменения цепочки прототипов.

В чем разница между классом и традиционным конструктором

  • Класс синтаксически больше соответствует объектно-ориентированному письму.
  • Наследование реализации класса стало более читабельным и понятным, а также более удобным для начинающих.
  • Суть по-прежнему синтаксический сахар, используя прототип

Десять, основное использование и принцип Promise

В мире JavaScript весь код выполняется в одном потоке. Из-за этой «баги» все сетевые операции в JavaScript, события браузера, должны выполняться асинхронно.Промисы — это решение для асинхронного программирования, более разумное и мощное, чем традиционные решения (обратные вызовы и события).

回调地狱

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

Принцип обещания

Однажды состояние изменилось, оно больше не изменится, и этот результат можно получить в любой момент. Есть только две возможности изменения состояния объекта Promise: с ожидания на выполнение и с ожидания на отклонение.Состояние инициализации объекта обещания — ожидание; когда вызывается разрешение (успех), оно будет ожидающим => выполнено; когда вызывается отклонение (сбой), оно будет ожидающим => отклонено. Конкретный процесс показан на следующем рисунке:

Promise原理

Процесс использования обещаний

  1. Экземпляр нового обещания и возврата
  2. Функция должна быть передана, когда новое обещание, функция имеет два параметра разрешения отклонения
  3. Выполнить разрешение в случае успеха и отклонить в случае неудачи
  4. затем слушайте результаты
function loadImg(src){
   const promise=new Promise(function(resolve,reject){
     var img=document.createElement('img')
     img.onload=function(){
        resolve(img)
   }
     img.onerror=function(){
        reject()
   }
    img.src=src
 })
  return promise//返回一个promise实例
}
var src="http://www.imooc.com/static/img/index/logo_new.png"
var result=loadImg(src)
result.then(function(img){
    console.log(img.width)//resolved(成功)时候的回调函数
},function(){
    console.log("failed")//rejected(失败)时候的回调函数
})
result.then(function(img){
    console.log(img.height)
})

Промисы упрощают поддержку кода, пишут асинхронный код, подобный синхронному, и упрощают понимание бизнес-логики.

11. Итератор и for...of циклы

Исходные структуры данных JavaScript, которые представляют «коллекции», в основном представляют собой массивы и объекты.ES6 добавляет Map и Set. Это требует единого механизма интерфейса для обработки всех различных структур данных. Итераторы — один из таких механизмов. Это интерфейс, обеспечивающий унифицированный механизм доступа к множеству различных структур данных.Любая структура данных может завершить операцию обхода до тех пор, пока развернут интерфейс Iterator (то есть все элементы структуры данных обрабатываются по очереди)..

1. Роль итератора:

  • Обеспечить единый и удобный интерфейс доступа к различным структурам данных;
  • Позволяет расположить элементы структуры данных в определенном порядке.
  • ES6 создал новую команду обхода цикла for...of, а интерфейс Iterator в основном используется для for...of потребления.

2. Собственные данные с интерфейсом итератора (для обхода)

  • Array
  • установить контейнер
  • контейнер карты
  • String
  • объект аргументов функции
  • Объект NodeList
let arr3 = [1, 2, 'kobe', true];
for(let i of arr3){
   console.log(i); // 1 2 kobe true
}
let str = 'abcd';
for(let item of str){
   console.log(item); // a b c d
}   
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
  console.log(e);
}
// Gecko
// Trident
// Webkit    

3. Сравнение нескольких методов обхода

  • Цикл for of поддерживает не только массивы, большинство объектов псевдомассивов, но и обход строк, а также обход объектов Map и Set.
  • Цикл for in может проходить по строкам, объектам, массивам, но не по Set/Map.
  • Цикл forEach не может проходить по строкам и объектам, но может проходить по Set/Map.

12. Модульность ES6

На уровне языковых стандартов ES6 реализует модульную функцию, и реализация достаточно проста, чтобы стать общим модульным решением для браузеров и серверов.Его функция модуля в основном состоит из двух команд: экспорта и импорта. Команда экспорта используется для указания внешнего интерфейса модуля, а команда импорта используется для импорта функций, предоставляемых другими модулями.

/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
    return a + b;
};
export { basicNum, add };
/** 引用模块 **/
import { basicNum, add } from './math';
function test(ele) {
    ele.textContent = add(99 + basicNum);
}

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

// export-default.js
export default function () {
  console.log('foo');
}

Приведенный выше код представляет собой файл модуля export-default.js, вывод которого по умолчанию является функцией.Когда другие модули загружают модуль, команда импорта может указать любое имя для анонимной функции.

// import-default.js
import customName from './export-default';
customName(); // 'foo'

Команда импорта в приведенном выше коде может использовать любое имя, чтобы указать на вывод метода export-default.js, тогда вам не нужно знать имя функции, выводимое исходным модулем.Следует отметить, что после команды импорта фигурные скобки не используются.

Если вы считаете, что статья немного полезна для вас, добро пожаловать вмой блог на гитхабеСтавьте лайк и подписывайтесь, большое спасибо!

Справочная статья

Примечания ES6 (1): «дефекты» JavaScript улучшены ES6

5 «ошибок» JavaScript, улучшенных в ES6

Начало работы с ECMAScript 6

Глубокое понимание ES6

Остальные параметры ES6 и оператор распространения