Прежде всего, поздравляю вас с Национальным праздником, испытайте радость жизни и поздравляю Родину с днем рождения, чтобы она становилась сильнее и процветала.
текст
1. пусть и константа
let
Использование похоже на var, но объявленная переменная действительна только в пределах блока кода, где находится команда let, то есть let объявляет переменную в пределах блока.
Функции:
- Нет переменного продвижения
- Временная мёртвая зона — пока в блочной области действия есть команда let, объявляемые ею переменные «привязаны» к этой области и больше не подвержены внешним воздействиям
- Дублирование деклараций не допускается.
- Область на уровне блока — заключена в {}, внешняя не может получить доступ к внутренней
Случаи применения и анализ:
// 使用var
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
});
} // => 5 5 5 5 5
// 使用let
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
});
} // => 0 1 2 3 4
В приведенном выше коде, использующем let, переменная i объявлена с помощью let, а текущая i действительна только в текущем цикле, поэтому i в каждом цикле на самом деле является новой переменной, и движок JavaScript запомнит значение предыдущей Cycle., когда инициализируется переменная i этого раунда, расчет выполняется на основе предыдущего раунда циклов, поэтому значение i может быть выведено в конце нормально.
Уведомление:
- Еще одна особенность цикла for заключается в том, что часть, которая устанавливает переменную цикла, является родительской областью, а внутренняя часть тела цикла — отдельной дочерней областью, поэтому мы можем получить доступ к значению i внутри тела цикла.
- Когда let и var объявлены глобально, доступ к var возможен через свойства окна, а к let — нет.
const
const объявляет константу только для чтения. После объявления значение константы не может быть изменено. На самом деле const гарантирует, что данные, хранящиеся в адресе памяти, на который указывает переменная, не могут быть изменены. Для простых типов данных (числа, строки, логические значения) значение сохраняется по адресу памяти, на который указывает переменная, поэтому оно эквивалентно константе. Но для данных составного типа (в основном объекты и массивы) адрес памяти, на который указывает переменная, является только указателем на фактические данные.const может гарантировать только фиксированность указателя.Что касается того, является ли структура данных, на которую он указывает, переменной. или нет, это полностью из-под контроля. Следовательно, объявление объекта константой должно выполняться с большой осторожностью.
Поэтому, когда мы используем const, мы не можем просто объявить и не инициализировать значение, иначе будет сообщено об ошибке:
const a;
// SyntaxError: Missing initializer in const declaration
Другие возможности const аналогичны let.Обычно рекомендуется объявлять константы, а имена констант писать с заглавной буквы.
2. Численное расширение
ES6 предоставляет новые методы Number.isFinite() и Number.isNaN() для объекта Number.
Number.isFinite()
Number.isFinite() используется для проверки того, является ли значение конечным, то есть не бесконечностью. Обратите внимание, что Number.isFinite всегда возвращает false, если тип параметра не является числовым.
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite('hello'); // false
Number.isFinite(true); // false
Number.isNaN()
Используется для проверки того, является ли значение NaN, если тип параметра не NaN, Number.isNaN всегда будет возвращать false
Разница между Number.isFinite и Number.isNaN и традиционными глобальными методами isFinite() и isNaN() заключается в том, что традиционный метод сначала вызывает Number() для преобразования нечислового значения в числовое значение, а затем оценивает, в то время как эти два новых метода Действительны только для числовых значений, Number.isFinite() всегда возвращает false для нечисловых значений, Number.isNaN() возвращает true только для NaN и false для не-NaN.
isFinite(11) // true
isFinite("11") // true
Number.isFinite(11) // true
Number.isFinite("11") // false
isNaN(NaN) // true
isNaN("NaN") // true
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
Number.isNaN(10) // false
Number.parseInt(), Number.parseFloat()
ES6 трансплантирует глобальные методы parseInt() и parseFloat() в объект Number, и поведение остается полностью неизменным Цель этого состоит в том, чтобы постепенно сокращать глобальные методы и делать язык постепенно модульным.
Number.isInteger()
Number.isInteger() используется для определения того, является ли значение целым числом; в JavaScript целые числа и числа с плавающей запятой используют один и тот же метод хранения, поэтому 25 и 25,0 считаются одним и тем же значением; если параметр не является значением, Number.isInteger возвращает false ; Поскольку значения JavaScript хранятся в 64-битном формате двойной точности, числовая точность может достигать 53 двоичных разрядов.Если точность числового значения превышает этот предел, 54-я и последующие цифры будут В этом случае Number.isInteger может быть неверно оценен.
Number.isInteger(15) // true
Number.isInteger(15.1) // false
Number.isInteger(15.0) // true
Number.isInteger('10') // false
Number.isInteger(true) // false
// 超出精度范围会误判
Number.isInteger(5.0000000000000002) // true
Math.trunc()
Метод Math.trunc используется для удаления дробной части числа и возврата целой части; для нечисловых значений Math.trunc внутренне использует метод Number для преобразования его в числовое значение; для нулевых значений и значений который не может быть усечен до целых, возвращает NaN
Math.trunc(2.1) // 2
Math.trunc(-2.9) // -2
Math.trunc(-0.1254) // -0
Math.trunc('125.456') // 125
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0
Math.trunc(NaN); // NaN
Math.trunc('bar'); // NaN
Math.trunc(); // NaN
Math.trunc(undefined) // NaN
Math.cbrt()
Метод Math.cbrt используется для вычисления кубического корня числа; для нечисловых значений метод Math.cbrt также использует метод Number для преобразования его в числовое значение.
Math.cbrt(-1) // -1
Math.cbrt(0) // 0
Math.cbrt(8) // 2
Math.cbrt('8') // 2
Math.cbrt('hello') // NaN
Math.hypot()
Метод Math.hypot возвращает квадратный корень из суммы квадратов всех аргументов.
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
Math.hypot(NaN); // NaN
Math.hypot(3, 4, 'foo'); // NaN
Math.hypot(3, 4, '5'); // 7.0710678118654755
Math.hypot(-3);
Удобно ли нам с этим API вычислять n-мерную теорему Пифагора?
Экспоненциальный оператор
ES2016 добавил оператор степени (**). Особенностью этого оператора является то, что он является правоассоциативным, а не обычным левоассоциативным. Когда несколько экспоненциальных операторов используются вместе, расчет начинается с крайнего правого.
// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2 // 512
// => Math.pow(2, Math.pow(3,2))
ES6+ также расширяет числовые API, и те, кто заинтересован, могут изучать и исследовать сами.
3. Расширение массива
спред оператор
Оператор распространения (spread) представляет собой три точки (...), которые превращают массив в последовательность аргументов, разделенных запятыми.
применение:
- копировать массив
const a1 = [1, 2];
const a2 = [...a1];
- Объединить массивы
const arr1 = ['1', '2'];
const arr2 = ['c', {a:1} ];
// ES6 的合并数组
[...arr1, ...arr2]
Примечание. Эти два метода являются неглубокими копиями, и при их использовании следует соблюдать осторожность.
- преобразовать строку в массив
Четырехбайтовые символы Unicode правильно распознаются с помощью оператора расширения. Любая функция, которая включает в себя манипулирование четырехбайтными символами Unicode, имеет эту проблему. Поэтому лучше всего переписать оба с оператором распространения.
[...'xuxi']
// [ "x", "u", "x", "i" ]
- Объект, реализующий интерфейс Iterator.
let nodeList = document.querySelectorAll('div');
let arr = [...nodeList];
В приведенном выше коде метод querySelectorAll возвращает объект NodeList. Это не массив, а массивоподобный объект. Оператор распространения может превратить его в настоящий массив, потому что объект NodeList реализует Iterator.
Array.from()
Метод Array.from используется для преобразования объектов класса в настоящие массивы: массивоподобные объекты и проходимые объекты (включая новые структуры данных ES6 Set и Map).
В практических приложениях мы используем Array.from more для коллекции NodeList, возвращаемой операциями DOM, а также объект arguments внутри функции.
// NodeList对象
let nodeList = document.querySelectorAll('p')
let arr = Array.from(nodeList)
// arguments对象
function say() {
let args = Array.from(arguments);
}
Array.from также может принимать второй параметр, аналогичный методу отображения массива, который используется для обработки каждого элемента и помещения обработанного значения в возвращаемый массив.
Array.from([1, 2, 4], (x) => x + 1)
// [2, 3, 5]
Array.of()
Метод Array.of используется для преобразования набора значений в массив. Array.of в основном может использоваться как замена для Array() или new Array(), и нет перегрузки из-за разных параметров. Он ведет себя очень равномерно.
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(2) // [2]
Array.of(21, 2) // [21, 2]
copyWithin() для экземпляров массива
Метод copyWithin() экземпляра массива внутри текущего массива копирует элементы в указанной позиции в другие позиции (перезаписывая исходные элементы), а затем возвращает текущий массив. То есть использование этого метода изменит текущий массив.
Он принимает три параметра:
- цель (обязательно): Начать замену данных в этой позиции. Если отрицательно, значит взаимно.
- start (необязательно): начать чтение данных с этой позиции, по умолчанию 0. Отрицательное значение означает отсчет с конца.
- конец (необязательно): прекратить чтение данных до достижения этой позиции, по умолчанию равно длине массива. Отрицательное значение означает отсчет с конца.
[11, 21, 31, 41, 51].copyWithin(0, 3) // => [41, 51, 31, 41, 51]
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
find() и findIndex() для экземпляров массива
Метод find экземпляра массива используется для поиска первого подходящего члена массива. Его параметр является функцией обратного вызова, и все элементы массива выполняют функцию обратного вызова по очереди, пока не будет найден первый элемент, возвращаемое значение которого равно true, а затем этот элемент возвращается. Возвращает неопределенное значение, если нет подходящих членов. Использование метода findIndex экземпляра массива очень похоже на метод find, который возвращает позицию первого подходящего члена массива или -1, если все члены не подходят. Оба этих метода могут принимать второй параметр, объект this, используемый для привязки функции обратного вызова.
// find
[1, 5, 8, 12].find(function(value, index, arr) {
return value > 9;
}) // 12
// findIndex
[1, 5, 5, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 3
// 第二个参数
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26
fill() для экземпляров массива
Метод fill заполняет массив заданными значениями. Метод fill также может принимать второй и третий параметры, определяющие начальную и конечную позиции заливки. Обратите внимание, что если заполненный тип является объектом, назначается объект по тому же адресу памяти, а не объект глубокой копии.
new Array(3).fill(7)
// [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
// 填充引用类型
let arr = new Array(2).fill({name: "xuxi"});
arr[0].name = "xu";
arr
// [{name: "xu"}, {name: "xu"}]
let arr = new Array(2).fill([]);
arr[0].push(1);
arr
// [[1], [1]]
include() для экземпляров массива
Метод Array.prototype.includes возвращает логическое значение, указывающее, содержит ли массив заданное значение. Второй параметр этого метода представляет начальную позицию поиска, которая по умолчанию равна 0. Если второй параметр отрицательный, то он указывает позицию обратного отсчета, а если он больше длины массива в это время (например, второй параметр равен -4, а длина массива равна 3), то он будет сброшен начать с 0.
[1, 4, 3].includes(3) // true
[1, 2, 4].includes(3) // false
[1, 5, NaN, 6].includes(NaN) // true
flat(), flatMap() для экземпляров массива
flat() используется для «выравнивания» вложенного массива в одномерный массив. Этот метод возвращает новый массив и не влияет на исходные данные. flat() будет "сглаживать" только один слой по умолчанию. Если вы хотите "сгладить" многослойный вложенный массив, вы можете записать параметр метода flat() как целое число, указывающее количество слоев, которые вы хотите flatten, который по умолчанию равен 1. Если вы хотите преобразовать его в одномерный массив независимо от того, сколько существует уровней вложенности, вы можете использовать ключевое слово Infinity в качестве параметра. Метод flatMap() выполняет функцию для каждого члена исходного массива, а затем выполняет метод flat() для возвращенного массива. Этот метод возвращает новый массив без изменения исходного массива. flatMap() может расширять только один уровень массива. Метод flatMap() также может иметь второй параметр, который используется для привязки внутри функции обхода.
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]
// 如果原数组有空位,flat()方法会跳过空位
[1, 2, , 4, 5].flat()
// [1, 2, 4, 5]
// flatMap
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
4. Расширение функций
Значения по умолчанию для параметров функции
function say(name = 'xuxi') {
alert(name)
}
будь осторожен:
- Переменные-параметры объявлены по умолчанию, поэтому их нельзя объявить снова с помощью let или const.
- При использовании параметров по умолчанию функции не могут иметь параметры с одинаковыми именами.
- Значение параметра по умолчанию не передается по значению, но значение выражения значения по умолчанию каждый раз пересчитывается. То есть значения параметров по умолчанию оцениваются лениво
- Если параметр передается в undefined, он приведет к тому, что параметр будет равен значению по умолчанию, и значение null не будет иметь такого эффекта. ключевой момент
Свойство длины функции
После указания значения по умолчанию свойство length функции вернет количество параметров без указанного значения по умолчанию. То есть после указания значения по умолчанию атрибут длины будет искажен, если параметр со значением по умолчанию не является хвостовым параметром, то атрибут длины больше не будет учитываться в следующих параметрах.
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
// 参数不是尾参数
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
сфера
Как только значение параметра по умолчанию установлено, параметр формирует отдельную область, когда функция объявляется инициализированной. Когда инициализация будет завершена, эта область исчезнет. Он не появится, если значение параметра по умолчанию не установлено.
стрелочная функция
Поскольку использование стрелочных функций относительно простое, давайте рассмотрим моменты, на которые следует обратить внимание:
-
Объект this в теле функции — это объект, в котором он определен, а не объект, в котором он используется.
-
Нельзя использовать как конструктор, то есть нельзя использовать новую команду, иначе будет выброшена ошибка.
-
Вы не можете использовать объект arguments, которого нет в теле функции. Если вы хотите использовать его, вы можете вместо этого использовать остальные параметры.
-
Команду yield нельзя использовать, поэтому стрелочные функции нельзя использовать в качестве функций-генераторов.
Не подходит для сценариев:
// 定义对象的方法,且该方法内部包括this,
// 因为对象不构成单独的作用域,导致say箭头函数定义时的作用域就是全局作用域
const person = {
year: 9,
say: () => {
this.year--
}
}
// 需要动态this的时候,也不应使用箭头函数
// 代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this是全局对象
var btn = document.getElementById('btn');
btn.addEventListener('click', () => {
this.classList.add('on');
});
5. Расширение объекта
Оператор распространения объекта
Оператор распространения (...) объекта используется для извлечения всех доступных свойств объекта параметра и их копирования в текущий объект, что эквивалентно использованию метода Object.assign().
let a = {w: 'xu', y: 'xi'}
let b = {name: '12'}
let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);
Object.is()
Он используется для сравнения того, являются ли два значения строго равными, что в основном совпадает с поведением оператора строгого сравнения (===); есть только два отличия: первое состоит в том, что +0 не равно -0 , а другой — что NaN равен самому себе.
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign()
Для слияния объектов скопируйте все перечисляемые свойства исходного объекта в целевой объект, если есть только один параметр, Object.assign вернет параметр напрямую, так как undefined и null не могут быть преобразованы в объекты, если они используются в качестве параметров, Будет сообщено об ошибке, другие типы значений (например, числа, строки и логические значения) не будут в первом параметре, и сообщение об ошибке не будет сообщено. Однако кроме того, что строка копируется в целевой объект в виде массива, другие значения не действуют.
// 合并对象
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
// 非对象和字符串的类型将忽略
const a1 = '123';
const a2 = true;
const a3 = 10;
const obj = Object.assign({}, a1, a2, a3);
console.log(obj); // { "0": "1", "1": "2", "2": "3" }
будь осторожен:
- Метод Object.assign выполняет поверхностную, а не глубокую копию. То есть, если значение свойства исходного объекта является объектом, то копия целевого объекта является ссылкой на этот объект.
- Для вложенных объектов при обнаружении свойства с тем же именем метод обработки Object.assign заключается в замене, а не добавлении
- Object.assign может использоваться для обработки массивов, но рассматривает массивы как объекты.
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
- Object.assign может только копировать значение.Если копируемое значение является функцией значения, оно будет оценено, а затем скопировано.
const a = {
get num() { return 1 }
};
const target = {};
Object.assign(target, a)
// { num: 1 }
Сценарии применения:
- Добавление свойств и методов к объектам
- клонировать/объединять объекты
- Укажите значения по умолчанию для свойств
Object.keys()
Возвращает массив, членами которого являются ключи всех проходимых свойств самого объекта параметра (за исключением унаследованных)
Object.values()
Возвращает массив, элементами которого являются ключи всех проходимых свойств самого объекта параметра (за исключением унаследованных). Примечание. Порядок членов возвращаемого массива: если имя атрибута является числовым атрибутом, он просматривается в соответствии с числовым значением, от меньшего к большему.
const obj = { 100: '1', 2: '2', 7: '3' };
Object.values(obj)
// ["2", "3", "1"]
Object.entries()
Возвращает массив, члены которого представляют собой массив пар ключ-значение всех проходимых свойств самого объекта параметра (за исключением унаследованных); если имя свойства исходного объекта является значением Symbol, свойство будет игнорироваться
const obj = { a: '1', b: 1, [Symbol()]: 123 };
Object.entries(obj)
// [ ["a", "1"], ["b", 1] ]
Object.fromEntries()
Метод Object.fromEntries() является операцией, обратной Object.entries(), которая используется для преобразования массива пар ключ-значение в объекты.
Object.fromEntries([
['a', '1'],
['b', 2]
])
// { a: "1", b: 2 }
Сценарии применения:
- Восстанавливает структуру данных пар ключ-значение в объекты, поэтому особенно подходит для преобразования структур карты в объекты.
- Взаимодействуйте с объектом URLSearchParams, чтобы преобразовать строку запроса в объект.
Object.fromEntries(new URLSearchParams('name=xuxi&year=24'))
// { name: "xuxi", year: "24" }
6. symbol
ES6 представляет новый примитивный тип данных Symbol, представляющий уникальное значение. Это седьмой тип данных в языке JavaScript.Первые шесть: undefined, null, Boolean, String, Number и Object. Значения символов генерируются функцией Symbol. Любое имя свойства, относящееся к типу Symbol, уникально, и можно гарантировать, что оно не будет конфликтовать с другими именами свойств.
будь осторожен:
- Новую команду нельзя использовать перед функцией Symbol, иначе будет сообщено об ошибке.
- Поскольку значения Symbol не являются объектами, свойства не могут быть добавлены. По сути, это строковый тип данных.
- Функция Symbol может принимать в качестве параметра строку, представляющую описание экземпляра Symbol, которое легко отличить
- Параметры функции Symbol просто представляют собой описание текущего значения Symbol, поэтому возвращаемые значения функции Symbol с теми же параметрами не равны
- Значения символов нельзя оперировать с другими типами значений, и будет сообщено об ошибке
- Когда значение Symbol используется в качестве имени свойства объекта, оператор точки использовать нельзя.
- Внутри объекта при определении свойства со значением Symbol значение Symbol должно быть заключено в квадратные скобки.
- Когда значение Symbol используется в качестве имени свойства, свойство по-прежнему является общедоступным, а не частным свойством.
- Когда Symbol используется в качестве имени свойства, свойство не будет отображаться в циклах for...in, for...of и не будет возвращено Object.keys(), Object.getOwnPropertyNames(), JSON.stringify( ). Однако оно также не является частным свойством.Используйте метод Object.getOwnPropertySymbols, чтобы получить все имена свойств Symbol указанного объекта.
Символ.для(), Символ.keyFor()
Symbol.for() принимает строку в качестве параметра и ищет значение Symbol с этим параметром в качестве имени. Если есть, верните значение Symbol, в противном случае создайте и верните значение Symbol со строкой в качестве имени. Метод Symbol.keyFor возвращает зарегистрированный ключ типа Symbol.
let a1 = Symbol.for('123');
let a2 = Symbol.for('123');
a1 === a2 // true
// Symbol.for()与Symbol()这两种写法,都会生成新的Symbol。
// 它们的区别是,前者会被登记在全局环境中供搜索,后者不会
Symbol.keyFor(a1) // "123"
let c2 = Symbol("f");
Symbol.keyFor(c2) // undefined
7. установить и сопоставить структуры данных
set
ES6 предоставляет новую структуру данных Set, которая похожа на массив, но значения членов уникальны и в них нет повторяющихся значений. Сам Set является конструктором, который генерирует структуру данных Set.
Свойства и методы экземпляра:
- add(value): добавить значение и вернуть саму структуру Set.
- удалить (значение): удалить значение и вернуть логическое значение, указывающее, было ли удаление успешным.
- has(value): возвращает логическое значение, указывающее, является ли значение членом набора.
- clear(): очищает все члены, без возвращаемого значения.
s.add(1).add(3).add(3);
// 注意3被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // false
s.delete(3);
s.has(3) // false
Операция обхода:
- keys(): возвращает обходчик имен ключей
- values(): итератор, который возвращает ключевые значения
- entry(): возвращает обход пар ключ-значение
- forEach(): выполняет итерацию по каждому члену, используя функцию обратного вызова.
Порядок обхода Set — это порядок вставки. Эта функция иногда очень полезна. Например, использование Set для сохранения списка функций обратного вызова может гарантировать, что они вызываются в порядке добавления.
Сценарии применения:
// 数组去重
let arr = [1,2,2,3];
let unique = [...new Set(arr)];
// or
function dedupe(array) {
return Array.from(new Set(array));
}
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
map
Подобно объектам, это также набор пар ключ-значение, и в качестве ключей могут использоваться различные типы значений (включая объекты). Структура Map обеспечивает соответствие «значение-значение» и является более полной реализацией структуры Hash.
Свойства и методы экземпляра:
- Свойство size: возвращает общее количество членов структуры Map.
- set(key, value): метод set устанавливает значение ключа, соответствующее ключу, а затем возвращает всю структуру карты. Если у ключа уже есть значение, значение ключа будет обновлено, в противном случае ключ будет сгенерирован заново.Метод set возвращает саму карту, поэтому можно использовать метод записи цепочки.
- get(key) : метод get считывает значение ключа, соответствующее ключу.Если ключ не найден, возвращается значение undefined
- has(key) : метод has возвращает логическое значение, указывающее, находится ли ключ в структуре данных карты.
- delete(key) : Метод удаления удаляет ключ и возвращает true. Возвращает false, если удаление не удалось
- clear(): метод clear очищает все элементы, не возвращает значение
Метод обхода аналогичен set, а структура Map преобразуется в структуру массива.Более быстрый способ — использовать оператор распространения (...) в комбинации:
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
[...map.keys()]
// [1, 2, 3]
[...map.values()]
// ['one', 'two', 'three']
[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]
[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]
Массив для отображения:
new Map([[true, 7], [{foo: 3}, ['abc']]])
// Map {true => 7, Object {foo: 3} => ['abc']}
Сопоставить с объектом:
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
Объект на карте
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// [ [ 'yes', true ], [ 'no', false ] ]
8. Прокси и отражение
Что касается введения Proxy и Reflect, я напишу отдельный модуль, чтобы представить их применение.
9. Объект обещания
Promise — это решение для асинхронного программирования, представляющее собой просто контейнер, содержащий результат события, которое завершится в будущем. Синтаксически Promise — это объект, из которого можно получить сообщение для асинхронной операции.
Функции:
- На состояние объекта не влияет внешний мир. Объект Promise представляет собой асинхронную операцию с тремя состояниями: Pending (выполняется), Resolved (завершено, также известное как Fulfilled) и Rejected (сбой). Только результат асинхронной операции может определить, какое состояние находится в данный момент, и никакая другая операция не может изменить это состояние.
- Однажды состояние изменилось, оно больше не изменится, и этот результат можно получить в любой момент. Весь процесс необратим.
использовать:
- Основное использование
// 实现异步加载图片
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
var image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('图片加载失败'));
};
image.src = url;
});
}
// 使用
loadImageAsync('http://xxxx/api').then((data) => {
// some code
}).catch(err => console.log(err))
Функция разрешения изменяет состояние объекта Promise с «незавершенного» на «успешное», то есть Pending => Resolved, и передает в качестве параметра результат асинхронной операции; функция reject изменяет состояние объекта Promise с "uncompleted" в "" Failed", то есть Pending => Rejected, и передать в качестве параметра ошибку, сообщенную асинхронной операцией.
После создания экземпляра Promise метод then можно использовать для указания функций обратного вызова для состояний Resolved и Reject соответственно. Первый параметр метода then — это функция обратного вызова состояния Resolved, а второй параметр (необязательный) — функция обратного вызова состояния Rejected.
Метод then возвращает новый экземпляр Promise (обратите внимание, не исходный экземпляр Promise). Следовательно, можно использовать метод цепочки, то есть после метода then вызывается другой метод then. Метод catch является псевдонимом для .then(null, rejection) и используется для указания функции обратного вызова при возникновении ошибки.
- Promise.all()
Метод Promise.all используется для переноса нескольких экземпляров Promise в новый экземпляр Promise. Только когда все состояния промиса в Promise.all будут выполнены, его состояние станет выполненным.В это время возвращаемое значение внутреннего промиса формирует массив и передается функции обратного вызова Promise.all. Пока обещание внутри Promise.all отклонено, состояние Promise.all становится отклоненным, и возвращаемое значение первого отклоненного экземпляра будет передано в функцию обратного вызова p.
- Promise.race()
Метод Promise.race также заключает несколько экземпляров Promise в новый экземпляр Promise. Пока один экземпляр Promise.race изменяет состояние первым, состояние Promise.race изменяется соответствующим образом. Возвращаемое значение экземпляра Promise, который изменился первым, передается в функцию обратного вызова Promise.race.
Реализовать обработку тайм-аута запроса:
const ajaxWithTime = (url, ms) => Promise.race([
fetch(url),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), ms)
})
])
ajaxWithTime('http://xxx', 5000).then(response => console.log(response))
.catch(error => console.log(error))
- Promise.resolve()
Преобразование существующего объекта в объект Promise. Если аргумент является экземпляром Promise, Promise.resolve вернет экземпляр без изменений и без изменений; если аргумент является примитивным значением или объектом без метода then, Promise.resolve вернет новый объект Promise, состояние — Resolved; следует отметить, что объект Promise, который разрешается немедленно, находится в конце текущего раунда «цикла событий» (цикла событий), а не в начале следующего раунда «цикла событий».
setTimeout(function () {
console.log('3');
}, 0);
Promise.resolve().then(function () {
console.log('2');
});
console.log('1');
// 1
// 2
// 3
- finally()
Метод finally используется для указания действия, которое будет выполняться независимо от конечного состояния объекта Promise. Он принимает в качестве параметра обычную функцию обратного вызова, которая должна быть выполнена в любом случае.
10. асинхронная функция
Асинхронная функция является синтаксическим сахаром Генераторной функции.После команды await асинхронной функции это может быть объект Promise и значение примитивного типа (числовое значение, строковое и логическое значение, но это эквивалентно синхронной операции ). Возвращаемое значение асинхронной функции — это объект Promise, и вы можете использовать метод then для указания следующего действия. Кроме того, асинхронную функцию можно рассматривать как несколько асинхронных операций, упакованных в объект Promise, а команда await является синтаксическим сахаром внутренней команды then.
Приложения:
1. Возврат данных через указанное время
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value)
}
asyncPrint('xu xi', 5000);
Меры предосторожности:
- Объект Promise, стоящий за командой await, может быть отклонен, поэтому лучше поместить команду await в блок кода try...catch.
- Асинхронные операции за несколькими командами ожидания, если нет вторичной связи, лучше позволить им запускаться одновременно.
let [a, b] = await Promise.all([a(), b()]);
- Команду await можно использовать только в асинхронных функциях, при использовании в обычных функциях будет выдано сообщение об ошибке.
Сценарии применения:
- Последовательное выполнение асинхронных операций
async function fetchInOrder(urls) {
// 并发读取远程请求
const promises = urls.map(async url => {
const res = await fetch(url);
return res.text();
});
// 按次序输出
for (const promise of promises) {
console.log(await promise);
}
}
11. class
С помощью ключевого слова class можно определить классы. Класс ES6 можно рассматривать как просто синтаксический сахар.Большинство его функций может быть достигнуто ES5.Метод написания класса просто делает метод написания прототипа объекта более понятным и более похожим на грамматику объектно-ориентированного программирования. Тип данных класса — функция, а сам класс указывает на конструктор. Свойство прототипа конструктора продолжает существовать в «классе» ES6. Все методы класса определяются в свойстве прототипа класса. Кроме того, все методы, определенные внутри класса, не являются перечисляемыми.
class Person {
constructor(){
// ...
}
toString(){
// ...
}
}
// 等同于
Person.prototype = {
toString(){},
toValue(){}
};
// 不可枚举
Object.keys(Person.prototype)
// []
Object.getOwnPropertyNames(Person.prototype)
// ["constructor","toString"]
// 注:ES5的写法,toString方法是可枚举的
метод конструктора
Этот метод является методом класса по умолчанию, который автоматически вызывается при создании экземпляра объекта с помощью новой команды. Класс должен иметь метод-конструктор, если он не определен явно, по умолчанию будет добавлен пустой метод-конструктор. Метод конструктора возвращает объект экземпляра (этот) по умолчанию, и вы можете указать, чтобы он возвращал другой объект.
Примечание. Конструктор класса нельзя вызвать без использования new, и будет сообщено об ошибке. Это главное отличие от обычных конструкторов, которые могут выполняться без оператора new.
Нет переменного продвижения
указатель на это
Если метод класса содержит это, по умолчанию он является экземпляром класса. Тем не менее, вы должны быть очень осторожны, поскольку этот метод используется один, он, вероятно, сообщит об ошибке.
// 解决this指向问题
class Say {
constructor() {
// 在构造方法中绑定this或者使用箭头函数
this.sayName = this.sayName.bind(this);
}
}
Наследование класса
Наследование между классами может быть достигнуто с помощью ключевого слова extends.Подклассы должны вызывать метод super в методе конструктора, иначе при создании нового экземпляра будет сообщено об ошибке. Это связано с тем, что подкласс не имеет собственного объекта this, а наследует объект this от родительского класса, и если суперметод не вызывается, то подкласс не получит этот объект.
class Color extends Point {
constructor(x, y, name) {
super(x, y); // 调用父类的constructor(x, y)
this.name = name;
}
toString() {
return this.name + ' ' + super.toString(); // 调用父类的toString()
}
}
Функция значения (геттер) и функция значения (сеттер) класса
Как и в ES5, ключевые слова get и set можно использовать внутри класса, чтобы установить функцию значения и функцию значения для свойства, а также перехватить поведение доступа к свойству.
class MyHTMLElement {
constructor(element) {
this.element = element;
}
get html() {
return this.element.innerHTML;
}
set html(value) {
console.log('success', value)
this.element.innerHTML = value;
}
}
const el = new MyHTMLElement(el);
el.html('1111') // success 1111
статический метод класса
Если ключевое слово static добавлено перед методом, это означает, что метод не будет унаследован экземпляром, а будет вызываться непосредственно через класс, который называется «статическим методом».
class Hi {
static say() {
return 'hello';
}
}
Hi.say() // 'hello'
let hi = new Hi();
hi.say()
// TypeError: foo.classMethod is not a function
12. Декоратор
модификация класса
Декоратор — это функция, которая изменяет поведение класса. Изменения в поведении класса происходят во время компиляции, а не во время выполнения.
function get(target) {
target.get = 'GET';
}
@get
class MyHttpClass {}
console.log(MyHttpClass.get) // GET
// 如果觉得一个参数不够用,可以在修饰器外面再封装一层函数
function get(type) {
return function(target) {
target.type = type;
// 添加实例属性
target.prototype.isDev = true;
}
}
@get('json')
class MyHttpClass {}
MyHttpClass.type // 'json'
let http = new MyHttpClass();
http.isDev // true
Модификация метода
Декоратор может не только изменять класс, но и свойства класса.Декоратор можно использовать только для класса и метода класса, а не для функции, потому что есть продвижение функции. Если есть несколько декораторов для одного и того же метода, это будет похоже на чистку луковицы: сначала вход снаружи внутрь, а затем выполнение изнутри наружу.
При изменении свойств класса функция декоратора может принимать в общей сложности три параметра: первый параметр — это целевой объект, который нужно изменить, второй параметр — это имя атрибута, который нужно изменить, а третий параметр — это описание. объект атрибута.
// 下面的@log修饰器,可以起到输出日志的作用
class Kinds {
list = []
@log
add(name) {
return this.list.push(name)
}
}
function log(target, name, descriptor) {
var oldValue = descriptor.value;
console.log('old', oldValue);
// ...
return descriptor;
}
const dog = new Kinds();
dog.add('dog');
// 多个装饰器的洋葱式执行顺序
function printN(id){
console.log('print-0', id);
return (target, property, descriptor) => console.log('print-1', id);
}
class A {
@printN(1)
@printN(2)
say(){}
}
// print-0 1
// print-0 2
// print-1 2
// print-1 1
13. module
Функция модуля в основном состоит из двух команд: экспорта и импорта. Команда экспорта используется для указания внешнего интерфейса модуля, а команда импорта используется для импорта функций, предоставляемых другими модулями.
export
Если вы хотите, чтобы снаружи можно было прочитать переменную внутри модуля, вы должны использовать ключевое слово экспорта для вывода переменной
// lib.js
// 直接导出
export var name = 'xu xi';
// 优先考虑下面这种写法,更清晰优雅
var year = 1958;
export {year};
//导出函数
export function multiply(x, y) {
return x * y;
};
// 使用as关键字重命名
export {
year as y
};
// 注意:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系
var a = 1;
// 报错,因为通过变量a,直接输出的是1,1只是一个值,不是接口
export a;
// 同理,下面的也会报错
function f() {}
export f;
// 另外,export语句输出的接口,与其对应的值是动态绑定关系,
// 即通过该接口,可以取到模块内部实时的值
export var a = 1;
setTimeout(() => a = 2, 1000); // 1s之后a变为2
Команда экспорта может появиться в любом месте модуля, если она находится на верхнем уровне модуля. Если он находится в области блочного уровня, он сообщит об ошибке, и то же самое верно для импорта. Это связано с тем, что в условном блоке кода нельзя выполнить статическую оптимизацию, что нарушает первоначальный замысел конструкции модуля ES6.
import
После использования команды экспорта для определения внешнего интерфейса модуля другие файлы JS могут загрузить модуль с помощью команды импорта. Команда импорта имеет эффект подъема, который будет поднят до головы всего модуля и выполнен первым. Это связано с тем, что команда импорта выполняется на этапе компиляции до запуска кода. Если один и тот же оператор импорта выполняется несколько раз, он будет выполнен только один раз, а не несколько раз.
// main.js
import {other, year} from './lib';
// 将输入的变量重命名
import { year as y } from './lib';
// 提升
say()
import { say } from './lib';
// 整体加载模块
import * as lib from './lib';
console.log(lib.year, lib.say())
команда экспорта по умолчанию
Укажите вывод по умолчанию для модуля
// a.js
export default function () {
console.log('xu xi');
}
// b.js
import a from './a'
Наконец
Поскольку более 90% задач в работе могут быть решены с помощью вышеуказанных новых функций es6, на более позднем этапе они будут продолжать оптимизироваться и улучшаться, и будет создан практический проект, полностью завершенный с использованием es6. Чтобы узнать больше о интерфейсе, присоединяйтесь к нам для обсуждения на официальном аккаунте «Интересный интерфейс»!
больше рекомендаций
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (включено)
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (средний)
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (ниже)
- Сведения о запуске на стороне сервера для реализации проекта полного стека CMS от 0 до 1 на основе nodeJS
- Краткое изложение основных знаний по теме "Продвинутое программирование на JavaScript"
- Используйте css3, чтобы реализовать фоновую анимацию потрясающего интервьюера (расширенный исходный код)
- Вспомните проблему межстраничной связи в старом проекте и фронтальную реализацию функции скачивания файлов.
- 5 минут, чтобы научить вас писать фиктивный сервер данных с помощью nodeJS
- Реализация и применение бинарного дерева и бинарного дерева поиска в JavaScript
- Реализация небольшой игры на проигрывателе с помощью JavaScript и C3
- Научу вас использовать 200 строк кода, чтобы написать любовную мини-игру Dou Pin Le H5 (с исходным кодом)
- Изучение и обобщение решений для внешней интеграции на основе экологии react/vue.
- Как написать собственную библиотеку js менее чем из 200 строк кода)
- Картинка, чтобы научить вас быстро играть в vue-cli3
- 3 минуты, чтобы научить вас использовать нативный js для реализации компонента предварительного просмотра загрузки файлов с мониторингом прогресса
- Использование Angular8 и API карты Baidu для разработки «списка туров»
- js реализация базового алгоритма поиска и тест производительности при 1,7 миллионах данных
- Как сделать интерфейсный код в 60 раз быстрее
- Vue advanced advanced series — играйте с vue и vuex с машинописным текстом