Предисловие (Введение в ECMAScript)
исходныйJavaScript
Существует 2 языковых стандарта:
ECMA-262
: Основной стандарт, разработанный ECMA International (Ecma International
) отвечает за управление (чтобы позволить начальноеJavaScript
с начальнымJScript
разработан в соответствии с одним и тем же набором стандартовECMAScript
, который выстраивается какEcma
из262
Стандартный, так что получитеECMA-262
Нумерация. )
ISO/IEC 16262
: Второй стандарт Международной организации по стандартизации.ISO
(International Standard Organization
) и Международной электротехнической комиссииIEC
(International Electrotechnical Commission
) отвечает за управление
По причинам авторского права на товарный знак канонический стандарт называет этот языкECMAScript
, так в принципеJavaScript
иECMAScript
Относится к одному и тому же, но иногда различается:
-
JavaScript
: относится к языку и его реализации -
ECMAScript
: Относится к языковым стандартам и языковым версиям, таким как ES6 для версии 6 языка (стандартная).
История развития ECMAScript
- ECMAScript 1 (июнь 1997 г.): первое издание спецификации.
- ECMAScript 2 (июнь 1998 г.): введены незначительные обновления для синхронизации стандартов ISO.
- ECMAScript 3 (декабрь 1999 г.): добавлены регулярные выражения, обработка строк, операторы управления (do-while, switch), обработка исключений (try-catch) и многие другие основные функции.
- Ecmascript 4 (отменено в июле 2008 года): Первоначально он был крупномасштабным обновлением (статическими типами, модулями, пространствами имен и т. Д.), Но пролет был слишком большим, были различия, и он не был широко использован
- ECMAScript 5 (декабрь 2009 г.): небольшие изменения, добавлены некоторые функции стандартной библиотеки и строгий режим.
- ECMAScript-5.1 (июнь 2011 г.): еще одно небольшое обновление для синхронизации со стандартами ISO.
- ECMAScript 6 (июнь 2015 г.): волна обновлений, реализация многих концепций ES4 того года и официальный переход на версии соглашения об именах по годам.
- ECMAScript 2016 (июнь 2016 г.): первый ежегодный выпуск с более коротким циклом выпуска и меньшим количеством новых функций, чем ES6.
- ECMAScript 2017 (июнь 2017 г.): второе ежегодное издание...
Будущие версии ECMAScript (ES2018, ES2019, ES2020 и т. д.) официально утверждены в июне.
Начало работы (сосредоточьтесь на ES6)
Цитата здесь阮一峰
учительскийES6标准入门
Краткое содержание книги: ES6 — это одновременно и исторический, и общий термин, означающий после версии 5.1.JavaScript
стандарты нового поколения, охватывающиеES2015、ES2016、ES2017
подожди, покаES2015
Это официальное название, конкретно относящееся к официальной версии языкового стандарта, выпущенной в том же году.Упоминание ES6 на рынке обычно относится кES2015
стандартный, но иногда общий下一代 JavaScript
В этой статье в основном объясняется следующее:
- Блочная область видимости (Block Scoping, ES2015)
- Деструктуризация (Destructuring, ES2015)
- Стрелочные функции (ES2015)
- строка шаблона (строка шаблона, ES2015)
- Параметры отдыха и спреда (ES2015)
- Сокращение литерала объекта (сокращение объекта, ES2015)
- include() для экземпляров массива (ES2016)
- Асинхронный синтаксис Async/await (ES2017)
область действия блока
Зачем вам нужна блочная область?
ES5 имеет только глобальную область действия и область действия функций, а не область действия на уровне блоков, что делает многие сценарии неразумными.
- В первом сценарии внутренние переменные могут переопределять внешние переменные.
var tmp = new Date()
function fn() {
console.log(tmp)
if (false) {
var tmp = 'hello world'
}
}
fn() // undefined
Исходное намерение приведенного выше кода состоит в том, что внешняя часть блока кода if использует внешнюю переменную tmp, а внутренняя часть использует внутреннюю переменную tmp. Однако функцияfn
После выполнения результат выводаundefined
, потому что продвижение переменной приводит к тому, что внутренняя переменная tmp перезаписывает внешнюю переменную tmp.
- Во втором сценарии переменная цикла, используемая для подсчета, передается как глобальная переменная.
var s = 'hello'
for (var i = O; i < s.length; i++) {
console.log(s[i])
}
console.log(i) // 5
В приведенном выше коде переменнаяi
Используется только для управления циклом, но после окончания цикла не исчезает, а просачивается в глобальную переменную.
let
фактическиJavaScript
Добавлена область действия блока.
function fl() {
let n = 5
if (true) {
let n = 10
}
console.log(n) // 5
}
Вышеупомянутая функция имеет два блока кода, оба объявляют переменные.n
, вывод после запуска5
. Это означает, что внешний кодовый блок не зависит от внутреннего кодового блока. При использованииvar
Определите переменную, и окончательное выходное значение будет10
тогда мы можем использовать块级作用域
что делать?
Давайте делать тротуар вопросы
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
// 5 5 5 5 5
изменить наES6
впустить
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
// 0 1 2 3 4
Увидев это, я думаю, вы поняли преимущества области видимости на уровне блоков.
ТакES5
Может ли это быть реализовано块级作用域
эффект? Да, мы можем использовать замыкания
for (var i = 0; i < 5; i++) {
;(function (index) {
setTimeout(() => {
console.log(index)
}, 1000)
})(i)
}
// 0 1 2 3 4
разрушать
Деструктуризация: это процесс разбиения структуры данных на более мелкие части. В ES6 извлекайте значения из массивов и объектов и присваивайте значения переменным.
Так в чем польза деконструкции?
- Операцию объявления переменных можно значительно упростить.
// ES5
var foo = 1
var bar = 2
var baz = 3
// ES6
let [foo, bar, baz] = [1, 2, 3]
- Variable Swap: выглядит как зеркальное отображение. Шаблон деструктурирования в левой части оператора присваивания и временно созданный литерал массива в правой части. x присваивается значение y в массиве, а y присваивается значение x в массиве.
let x = 1
let y = 2
;[x, y] = [y, x]
// x = 2, y = 1
- деструктуризация объекта
var obj = { x: 1, y: 2, c: 1 }
let { x, y } = obj
// x = 1
// y = 2
- Деструктуризация строки
const [a, b, c, d, e] = 'hello'
// a => h
// b => e
// c => l
// d => l
// e => o
- деструктуризация параметра функции
const xueyue = {
name: '雪月',
age: 18,
}
function getAge({ name, age }) {
return `${name}今年${age}岁`
}
getAge(xueyue) // 雪月今年18岁
стрелочная функция
ES6
Стрелки разрешены=>
определить функцию
var f = v => v
// 等同于 ES5 的
var f = function (v) {
return v
}
Если стрелочная функция не требует параметров или требует более одного параметра, используйте круглые скобки для представления части параметра.
var f = () => 5
// 等同于 ES5 的
var f = function () {
return 5
}
var sum = (numl, num2) => numl + num2
// 等同于 ES5 的
var sum = function (numl, num2) {
return numl + num2
}
Стрелочные функции можно использовать в сочетании с деструктурированием.
const full = ({ first , last }) => first + ' ' + last;
// 等同于 ES5 的
function full(person) {
return person.first + ' ' + person.last;
}
Стрелочные функции делают выражения более краткими
const isEven = n => n % 2 === 0
const square = n => n * n
var result = values.sort((a, b) => a - b)
// 等同于 ES5 的
var result = values.sort(function (a, b) {
return a - b
})
В приведенном выше коде используются только две строки, определяющие две простые функции инструмента. Если вам не нужны стрелочные функции, вы можете занять несколько строк, и лучше написать свой глаз.
Примечания по использованию стрелочных функций
- внутри функции
this
Объект — это объект, в котором он определен, а не объект, в котором он используется. - нельзя использовать в качестве конструктора, то есть нельзя использовать
new
команду, иначе будет выдана ошибка. - недоступно
arguments
объект, который не существует в теле функции. Если вы хотите использовать его, вы можете использоватьrest
вместо этого параметр. - недоступно
yield
команду, поэтому функции стрелок нельзя использовать в качествеGenerator
функция.
Из четырех пунктов, приведенных выше, особенно следует отметить первый.this
Указатель на объект изменяем, но в стрелочных функциях он фиксирован.
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id)
}, 100)
}
// 转换成ES5
function foo() {
var _this = this
setTimeout(function () {
console.log('id:', _this.id)
}, 100)
}
В приведенном выше коде преобразованныйES5
Версия четко утверждает, что функции стрелки не имеют своих собственныхthis
, но обратитесь к внешнемуthis
.
строка шаблона
Строка шаблона — это расширенная версия строки, заключенная в обратные кавычки.
(``)
Я БЫ . Его можно использовать как обычную строку, его также можно использовать для определения многострочных строк или для встраивания переменных в строки.
const { log } = console
const name = '雪月'
const age = 18
// 普通字符串拼接
const result = name + '今年' + age + '岁'
// 使用模板字符串
const result2 = `${name}今年${age}岁`
log(result) // 雪月今年18岁
log(result2) // 雪月今年18岁
// ${} 大括号可以放入任意的 JavaScript 表达式,可以进行运算
const result3 = `${name}今年${age * 2}岁`
log(result3) // 雪月今年36岁
Оставшиеся аргументы / расширение синтаксиса
ES6 представил остальные параметры (в форме...变量名
), используется для получения дополнительных параметров функции, так что нет необходимости использоватьarguments
объект.rest
Переменная совместного размещения параметров представляет собой массив, в который помещаются избыточные параметры.
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort()
}
// 使用 rest
const sortNumbers = (...numbers) => numbers.sort()
Сравнивая два вышеприведенных способа записи, можно обнаружить, что,rest
Параметры написаны более естественно и лаконично.
оператор спреда (spread
) представляют собой три точки (...), как вrest
Инверсия аргументов Преобразует массив в последовательность аргументов, разделенных запятыми.
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
Вот оператор спреда вместоapply
Практический пример применения методаMath.max
Метод упрощает поиск самого большого элемента в массиве.
// ESS 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77)
Оператор распространения предоставляет новый способ объединения массивов.
// ESS
;[1, 2].concat(more)
// ES6
;[1, 2, ...more]
Оператор распространения (...) объекта используется для извлечения всех проходимых свойств объекта параметра и их копирования в текущий объект.
let z = { a: 3, b: 'bb' }
let n = { ...z }
n // { a: 3, b: 'bb' }
n === z // false
обращать внимание: ...
Расширение объекта может быть выполнено только тогда, когда свойство объекта基本数据类型
является深拷贝
,если引用数据类型
,Это浅拷贝
.
let z = { a: 3, b: 'bb', c: { name: 'ccc' } }
let n = { ...z }
n // { a: 3, b: 'bb', c: { name: 'ccc' } }
n === z // false
n.c === z.c // true
// n.c 跟 z.c 是同一个引用地址
Сокращенный синтаксис объектного литерала
const name = '雪月'
// ES5写法
const obj = {
name: name,
f: function () {
console.log(this.name)
},
}
// ES6简写
const obj2 = {
name,
f() {
console.log(this.name)
},
}
obj.f() // 雪月
obj2.f() // 雪月
использоватьvue
Ваши одноклассники чувствуют себя знакомыми?
new Vue({
el: '#app',
data() {
return {
list: [],
}
},
})
include() для экземпляров массива
Метод Array.prototype.includes возвращает логическое значение, указывающее, содержит ли массив заданное значение, аналогично методу include для строк. ES2016 представил этот метод.
;[1, 2, 3].includes(2) // true
;[1, 2, 3].includes(4) // false
;[1, 2, NaN].includes(NaN) // true
До этого метода мы обычно использовали метод indexOf массива, чтобы проверить, содержит ли он определенное значение.
// ES5
if (arr.indexOf(el) !== -1) {
// ...
}
// ES6
if (arr.includes(el)) {
// ...
}
// 那么 indexOf 能不能做到类似于 includes 的写法呢? 我们可以利用 ~ 位运算符
if (~arr.indexOf(el)) {
// ...
}
indexOf
У метода есть два недостатка.Одним из них является то, что он недостаточно семантичен.Его смысл в том,чтобы найти первое вхождение значения параметра,поэтому он недостаточно интуитивен,чтобы сравнить,не равно ли оно -1. Во-вторых, он использует оператор строгого равенства (===) внутри для суждения, что приводит кNaN
неправильное объявление.
;[NaN].indexOf(NaN)
// -1
includes
Если вы используете другой алгоритм оценки, проблем нет.
;[NaN].includes(NaN)
// true
Асинхронный/ожидающий асинхронный синтаксис
ES2017
введен стандартasync
Функции, которые делают асинхронные операции более удобными.
async
Что такое функция? Одним словом, этоGenerator
Синтаксический сахар для функций.
async function getTitle(url) {
let response = await fetch(url)
let html = await response.text()
return html.match(/<title>([\s\S]+)<\/title>/i)[1]
}
getTitle('https://tc39.github.io/ecma262/').then((res) => console.log(res))
В приведенном выше коде функцияgetTitle
Внутри три операции:抓取网页
,取出文本
,匹配页面标题
. Только после того, как все три операции будут завершены, он будет выполненthen
в методеconsole.log
конец (незаконченный)
Статья знакомитES6
Некоторые общие синтаксис и сценарии использования; ноES6
Содержание гораздо больше, чем это, заинтересованные студенты могут перейти к阮一峰老师的
Руководство по началу работы с ES6Подробности смотрите в книге. Если вы узнали эту книгу, вы также можете купить ее по официальным каналам. Это предотвратит потерю денег издателями при публикации книг с открытым исходным кодом, тем самым поощряя больше авторов открывать свои книги с открытым исходным кодом.
Постскриптум (список API)
Есть намного большеES6
ПолезныйAPI
Я кратко упомяну об этом, друзья, чтобы увидеть, полезно ли это в обычное время.
;[1, 4, -5, 10].find(n => n < 0)
// -5
;[1, 5, 10, 15].findIndex((value, index, arr) => value > 9)
// 2
;[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
;[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
;[3, 8, 54, 8, 3, NaN, NaN, 'NaN', 'NaN'].filter((number, index, arr) => arr.indexOf(number) === index)
// [3, 8, 54, "NaN"] 利用filter过滤去重,注意会漏掉NaN
;[1, 2, 3, 4].map((item) => item * 2)
// [2, 4, 6, 8] 利用map返回一个新数组,不改变原数组
// 使用 reduce 求和; reduce功能极其强大 ! yyds
;[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
// 10
// ES2017 引入了跟 Object.keys 配套的 Object.values 和 Object.entries,作为遍历一个对象的补充手段,
// 供 for...of 循环使用。
let { keys, values, entries } = Object;
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}