напишите в начале
-
ES6Распространенные, но игнорируемые методыСерия статей, в которых рассматриваются некоторые методы, навыки использования и некоторые сценарии применения, которые, по мнению автора, могут быть использованы для ежедневной разработки.
Статьи по Теме
- Общие, но игнорируемые методы ES6 (первое деструктурирование присваиваний и значений)
- Обычно используемые, но игнорируемые методы ES6 (символ третьего маркера, набор и карта)
- Широко используемые, но игнорируемые методы ES6 (четвертый пункт Proxy и Reflect)
- Часто используемые, но игнорируемые методы ES6 (обещание и итератор пятой бомбы)
- Часто используемые, но игнорируемые методы ES6 (генератор шестого генератора)
- Часто используемые, но игнорируемые методы ES6 (седьмой пункт асинхронности)
- Обычно используемые, но игнорируемые методы ES6 (восьмой класс бомб)
- Часто используемые, но игнорируемые методы ES6 (девятый модуль)
- Широко используемые, но игнорируемые методы ES6 (десятая спецификация разработки проекта)
- Часто используемые, но игнорируемые методы ES6 (одиннадцатый декоратор бомбы)
- Обычно используемые, но игнорируемые методы ES6 (последний пункт — последнее предложение)
расширение функции
значение функции по умолчанию
- Функция может назначить значение по умолчанию, определив соответствующие параметры, и значение по умолчанию используется, если функция вызывается при вызове функции. Установка значения по умолчанию также может использоваться с деконструированным назначением.
function detanx(x = 1) { ... }
// 搭配解构赋值
function detanx({name, age = 10} = {name: 'detanx', age: 10}) {...}
// 不完全解构,
function detanx({name, age = 10} = {name: 'detanx'}) {...}
detanx({age: 12}) // undefined 12
- В случае неполной деструктуризации, даже если в следующем объекте есть соответствующее значение ключа, оно не будет присвоено.
- Параметры функции со значениями по умолчанию находятся в середине числа параметров, а следующие параметры не используют значения по умолчанию, В этом случае можно передать параметры для использования значений по умолчанию.
undefined.
function detanx(x = null, y = 6) {
console.log(x, y);
}
detanx(undefined, null); // null null
- Значение по умолчанию изменится
lengthПолучите длину, возвращаемую параметром функции.
- После указания значения по умолчанию функция
lengthсвойство, вернет количество параметров без указанного значения по умолчанию. То есть, после указания значения по умолчанию,lengthАтрибуты будут искажены.
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
-
Параметр значения по умолчанию не является хвостовым параметром, тогда
lengthАтрибуты также больше не учитываются в следующих параметрах.
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
- Используйте оператор распространения для представления полученных параметров,
lengthдля0.
(function(...args) {}).length // 0
- Область действия изменена после установки значения по умолчанию
- Значение параметра по умолчанию установлено, и при объявлении и инициализации функции параметр сформирует отдельную область видимости (
context).
var x = 1;
function detanx(x, y = x) {
console.log(y);
}
f(2) // 2
function detanx(x = x, y = x) {
console.log(x, y);
}
f(undefined,2) // ReferenceError: Cannot access 'x' before initialization
приложение значения по умолчанию функции
- Указание параметра не должно быть опущено, если опущено, выдается ошибка.
function throwIfMissing() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()) {
return mustBeProvided;
}
foo()
// Error: Missing parameter
- параметр
mustBeProvidedЗначение по умолчанию равноthrowIfMissingРезультат выполнения функции (обратите внимание на имя функцииthrowIfMissingСодержит пару скобок), которая указывает на то значение параметра по умолчанию не выполняется в определении времени, но во время выполнения. Если параметр уже назначен, функция в значение по умолчанию не будет работать.
Строгий изменение режима
-
ES5Сначала функцию можно установить в строгий режим внутри.ES2016Была сделана небольшая модификация, чтобы указать, что до тех пор, пока параметры функции используют значения по умолчанию, деструктурирующие присваивания или операторы расширения, функция не может быть явно установлена в строгий режим, иначе будет сообщено об ошибке.
// 报错
function doSomething(a, b = a) {
'use strict';
// code
}
// 报错
const doSomething = function ({a, b}) {
'use strict';
};
// 报错
const doSomething = (...a) => {
'use strict';
};
const obj = {
// 报错
doSomething({a, b}) {
'use strict';
}
};
- Проблема с этим ограничением заключается в том, что при объявлении сначала выполняются параметры, а затем выполняется тело функции, и только при входе в тело функции и обнаружении, что используется строгий режим, будет сообщено об ошибке.
- Способы обойти это ограничение.
// 第一种是设定全局性的严格模式,这是合法的。
'use strict';
function doSomething(a, b = a) {
// code
}
// 第二种是把函数包在一个无参数的立即执行函数里面。
const doSomething = (function () {
'use strict';
return function(value = 42) {
return value;
};
}());
стрелочная функция
- Примечания по использованию
- внутри функции
thisОбъект — это объект, в котором он определен, а не объект, в котором он используется. - нельзя использовать в качестве конструктора, то есть нельзя использовать
newкоманду, иначе будет выдана ошибка. - недоступно
argumentsобъект, который не существует в теле функции. Если вы хотите использовать его, вы можете использоватьrestвместо этого параметр. - недоступно
yieldкоманду, поэтому функции стрелок нельзя использовать в качествеGeneratorфункция.
- внутри функции
- Стрелочные функции также могут быть вложены как обычные функции.
- Упрощает написание кода, но снижает его читабельность.
// 柯里化
const curry = (fn, arr = []) => (...args) => (
arg => arg.length === fn.length
? fn(...arg)
: curry(fn, arg)
)([...arr, ...args]);
let curryTest = curry( (a, b) => a + b );
curryTest(1, 2) //返回3
curryTest(1)(2) //返回3
расширение массива
спред оператор
- заявление
- Получить неопределенное количество параметров
function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10- заменять
applyметод
- Раньше, когда функции нужно было получить параметр массива, ее нужно было писать так
fn.apply(this, arr).
// ES5 的写法 const args = [0, 1, 2]; function f(x, y, z) { // ... } f.apply(null, args); // ES6的写法 function f(x, y, z) { // ... } f(...args);- Копировать, объединять массивы, преобразовывать строки в массивы
const a = [1] const b = [2]; // 复制数组 const c = [...a]; // [1] // 合并数组 [...a, ...b, ...c] // [1, 2, 1] // 转换字符串为数组 [...'detanx'] // ['d', 'e', 't', 'a', 'n', 'x']- Достигнуто
Iteratorобъект интерфейса
- Все, что определяет обходчик (
Iterator) объект интерфейса (см.IteratorГлава 1), можно преобразовать в реальный массив с помощью оператора расширения.
Number.prototype[Symbol.iterator] = function*() { let i = 0; let num = this.valueOf(); while (i < num) { yield i++; } } console.log([...5]) // [0, 1, 2, 3, 4]- например функция
argumentsобъект похож на массив;querySelectorAllметод возвращаетNodeListобъект. Это также массивоподобный объект.
let nodeList = document.querySelectorAll('div'); let array = [...nodeList];
Array.from
-
Array.fromЭта функция аналогична оператору расширения, который может преобразовывать массив, подобный массиву, в массив, но также может получать второй параметр, аналогичный параметру массива.mapметод для обработки каждого элемента и помещения обработанного значения в возвращаемый массив.
// 生成0-99的数组
Array.from(new Array(100), (x, i) => i);
copyWithin()
- экземпляр массива
copyWithin()Метод внутри текущего массива копирует элементы указанной позиции в другие позиции (перезаписывает исходные элементы), а затем возвращает текущий массив. То есть использование этого метода изменит текущий массив.Array.prototype.copyWithin(target, start = 0, end = this.length)-
target(обязательно): заменить данные, начиная с этой позиции. Если отрицательно, значит взаимно. -
start(необязательно): начать чтение данных с этой позиции, по умолчанию0. Отрицательное значение означает отсчет с конца. -
end(Необязательно): Остановить чтение данных до достижения этой позиции, значение по умолчанию равно длине массива. Отрицательное значение означает отсчет с конца.
-
- Все три параметра должны быть числовыми значениями, в противном случае они будут автоматически преобразованы в числовые значения.
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}
// 将2号位到数组结束,复制到0号位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// 对于没有部署 TypedArray 的 copyWithin 方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
найти() и найтииндекс()
- Оба метода могут получать два параметра, первый параметр — это функция обратного вызова (может принимать три параметра, а именно текущее значение, текущая позиция, текущий исходный массив), второй параметр используется для привязки функции обратного вызова.
this. Разница в том,findвозврат не найденundefined,findIndexто, что возвращается-1. Оба метода можно найтиNaN, что составляет массивindexOfнедостаточность метода.
[1, 4, -5, 10].find((n) => n > 10) // undefined
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 15;
}) // -1
// 绑定this
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26
// 找出NaN
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0
fill
-
fillМетод заполняет массив заданными значениями.
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
-
Приведенный выше код показывает, что
fillМетод очень удобен для инициализации пустых массивов. Все существующие элементы в массиве будут стерты. -
fillМетод также может принимать второй и третий параметры, которые указывают, где начинается и заканчивается заполнение.
- ['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
- Приведенный выше код говорит,
fillметод из1Начните с позиции числа, заполните исходный массив7,прибыть2заканчиваться перед числом.
Обратите внимание, что если заполнение типа object, то объекту присваивается тот же адрес памяти, а не глубокая копия объекта.
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
let arr = new Array(3).fill([]);
arr[0].push(5);
arr
// [[5], [5], [5]]
includes
- содержит ли массив заданное значение, такое же, как и строка
includesМетод аналогичен. а такжеindexOfРазница в том,includesвозвращает логическое значение напрямую,indexOfНеобходимо определить, является ли возвращаемое значение-1. Его можно использовать, когда нам нужно, является ли переменная одним из нескольких значений перечисления.includes.
const name = 'detanx';
const nameArr = ['detanx', 'det', 'tanx']
// 使用includes做判断
if(nameArr.indexOf(name) !== -1) { ... }
=>
if(nameArr.includes(name)) { ... }
// 判断name是否是 detanx,tanx,det
if(name === 'detanx' || name === 'det' || name === 'tanx') {...}
=>
nameArr.includes(name);
пространство массива
- Вакансия массива означает: в определенной позиции массива нет значения (вакансия не
undefined, значение позиции равноundefined, по-прежнему ценен. ). Например,ArrayМассив, возвращаемый конструктором, пуст.
Array(3) // [, , ,]
-
forEach(),filter(),reduce(),every()а такжеsome()пропустит вакансию.
// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1
// filter方法
['a',,'b'].filter(x => true) // ['a','b']
// every方法
[,'a'].every(x => x==='a') // true
// reduce方法
[1,,2].reduce((x,y) => x+y) // 3
// some方法
[,'a'].some(x => x !== 'a') // false
-
map()Пустые биты пропускаются, но значение сохраняется.
// map方法
[,'a'].map(x => 1) // [,1]
-
join()а такжеtoString()будет рассматривать вакансии какundefined,а такжеundefinedа такжеnullбудет рассматриваться как пустая строка.
// join方法
[,'a',undefined,null].join('#') // "#a##"
// toString方法
[,'a',undefined,null].toString() // ",a,,"
-
Array.from(),...,entries(),keys(),values(),find()а такжеfindIndex()будет рассматривать вакансию какundefined.
Array.from(['a',,'b'])
// [ "a", undefined, "b" ]
[...['a',,'b']]
// [ "a", undefined, "b" ]
// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]
// keys()
[...[,'a'].keys()] // [0,1]
// values()
[...[,'a'].values()] // [undefined,"a"]
// find()
[,'a'].find(x => true) // undefined
// findIndex()
[,'a'].findIndex(x => true) // 0
-
copyWithin(),fill(),for...ofПустые позиции рассматриваются как обычные позиции массива.
[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]
new Array(3).fill('a') // ["a","a","a"]
let arr = [, ,];
for (let i of arr) {
console.log(1);
}
// 1
// 1
- Правила обращения с вакансиями очень противоречивы, поэтому рекомендуется избегать вакансий.
расширение объекта
Перечисление свойств объекта
- Каждое свойство объекта имеет объект описания (
Descriptor) для управления поведением этого свойства.
Object.getOwnPropertyDescriptorметод для получения объекта описания свойства.
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
-
описание объекта
enumerableсвойство, называемое «перечислимостью», если свойствоfalse, что означает, что некоторые операции игнорируют текущее свойство. -
В настоящее время игнорируются четыре операции.
enumerableдляfalseхарактеристики.-
for...inЦикл: перебирать только собственные и унаследованные перечисляемые свойства объекта. -
Object.keys(): возвращает ключевые имена всех перечисляемых свойств самого объекта. -
JSON.stringify(): сериализовать только перечисляемые свойства самого объекта. -
Object.assign(): халатное отношениеenumerableдляfalseproperties копируются только перечисляемые свойства самого объекта.
-
-
SymbolАтрибуты типа могут быть переданы толькоgetOwnPropertySymbolsспособ получения.
оператор цепной оценки
-
ES5Определяем, имеет ли объект глубокого уровня определенныйkeyЕго нужно судить слой за слоем, и теперь мы можем пройти?.способ получения.
// es5
// 错误的写法(当某一个key不存在undefined.key就会代码报错)
const firstName = message.body.user.firstName;
// 正确的写法
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
// es6
const firstName = message?.body?.user?.firstName || 'default';
- Существует три варианта использования оператора предиката цепочки.
-
obj?.prop// свойства объекта -
obj?.[expr]// свойства объекта -
func?.(...args)// вызов метода функции или объекта
-
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()
- будь осторожен
- механизм короткого замыкания
-
?.Оператор эквивалентен механизму короткого замыкания, пока условие не выполнено, он не будет выполняться дальше.
// 当name不存在时,后面的就不再执行 user?.name?.firstName-
deleteоператор
delete a?.b // 等同于 a == null ? undefined : delete a.b- В приведенном выше коде, если
aдаundefinedилиnull, вернется напрямуюundefined, вместоdeleteоперация.
- Эффект скобок
- Если в цепочке свойств есть круглые скобки, оператор оценки цепочки не влияет на внешнюю сторону круглых скобок, а только на внутреннюю часть круглых скобок.
(a?.b).c // 等价于 (a == null ? undefined : a.b).c- Отчет об ошибках
- Следующее написание запрещено, и будет сообщено об ошибке.
// 构造函数 new a?.() new a?.b() // 链判断运算符的右侧有模板字符串 a?.`{b}` a?.b`{c}` // 链判断运算符的左侧是 super super?.() super?.foo // 链运算符用于赋值运算符左侧 a?.b = c- Правая часть не должна быть десятичным числом
- Чтобы обеспечить совместимость с предыдущим кодом, разрешите
foo?.3:0анализируется вfoo ? .3 : 0, так что если?.затем десятичная цифра, затем?.Он больше не считается полным оператором, а будет рассматриваться как тернарный оператор, то есть десятичная точка будет приписываться следующему десятичному числу, образуя десятичное число.
Nullоператор??
- При чтении свойств объекта, если значение свойства равно
nullилиundefined, иногда необходимо указать для них значения по умолчанию. Обычная практика заключается в||оператор указывает значение по умолчанию. ||оператор, когда левая часть представляет собой пустую строку илиfalseтакже установит значение по умолчанию, когда??оператор, только если левая сторонаnullилиundefinedБудет установлено значение по умолчанию.
// || 运算
const a = '';
b = a || 1;
console.log(b) // 1
// ?? 运算
b = a ?? 1;
console.log(b) // ''
??Существует проблема с приоритетом операции, связанная с&&а также||Приоритет выше или ниже, поэтому при совместном использовании для указания приоритета необходимо использовать круглые скобки, иначе будет сообщено об ошибке.
Object.is()
- Используется для сравнения двух значений на строгое равенство, в отличие от оператора строгого сравнения (
===) в принципе одинаковы.
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
- Отличий всего два: одно
+0не равно-0, дваNaNравно самому себе.
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign
- Для слияния объектов исходный объект (
source) всех собственных свойств (без копирования унаследованных свойств), свой собственныйSymbolСвойства-значения и перечисляемые свойства (enumerableдляtrue), копируется в целевой объект (target). Первый параметр — это целевой объект, за которым следует исходный объект.
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}
// 拷贝Symbol值属性
Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
// { a: 'b', Symbol(c): 'd' }
- входящий
nullа такжеundefinedсообщит об ошибке.
Object.assign(undefined) // 报错
Object.assign(null) // 报错
- будь осторожен
-
Object.assignМетод выполняет поверхностную копию, а не глубокую копию. - При обнаружении свойства с тем же именем,
Object.assignПодход заключается в том, чтобы заменить, а не добавить. - обработка массива
-
Object.assignможно использовать для работы с массивами, нообрабатывать массивы как объекты.
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3] -
- Обработка функций значений
-
Object.assignТолько значение может быть скопировано, если копируемое значение является функцией значения, оно будет оценено, а затем скопировано.
const source = { get foo() { return 1 } }; const target = {}; Object.assign(target, source) // { foo: 1 } -
Object.keys(), Object.values(), Object.entries()
Object.keys()
-
ES5представилObject.keysметод, который возвращает массив, все элементы которого доступны для обхода (без наследования) самого объекта параметра (enumerable) Атрибут имени ключей. Если мы просто принесем объектные клавиши, вы можете использовать это место.
let obj = { a: 1, b: 2, c: 3 };
for (let key of Object.keys(obj)) {
console.log(key); // 'a', 'b', 'c'
console.log(obj[key]) // 1, 2, 3
}
Object.values()
- такой же
Object.keysразница заключается в возвращаемом ключе и возвращаемом значении. С помощью этого метода невозможно получить имя ключа.
let obj = { a: 1, b: 2, c: 3 };
for (let value of Object.values(obj)) {
console.log(value); // 1, 2, 3
}
// 数值的键名
const obj = { 100: 'a', 2: 'b', 7: 'c' };
Object.values(obj)
// ["b", "c", "a"]
- Атрибуты, имя атрибута которых является числовым значением, перебираются в соответствии с числовым значением, от меньшего к большему, поэтому возвращаемый порядок
b,c,a. Object.valuesбудет фильтровать свойства с именемSymbolсвойство стоимости.
Object.entries()
-
Object.entries()Метод возвращает число, за исключением того, что тип возвращаемого значения другой, остальные действия такие же, какObject.valuesВ основном то же самое.
for (let [key, value] of Object.entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
- Для обхода объектов я теперь использую следующий способ записи
Object.entries(obj).forEach(([key, value]) => {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
})
Object.fromEntries()
-
Object.fromEntries()путьObject.entries()Обратная операция для преобразования массива пар ключ-значение в объект. Основная цель — восстановить структуру данных пар ключ-значение для объектов.
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
-
MapСтруктура представляет собой массив пар ключ-значение, поэтому она очень подходит дляMapСтруктуры в объекты.
// 例一
const entries = new Map([
['foo', 'bar'],
['baz', 42]
]);
Object.fromEntries(entries)
// { foo: "bar", baz: 42 }
// 例二
const map = new Map().set('foo', true).set('bar', false);
Object.fromEntries(map)
// { foo: true, bar: false }