В этой статье в основном описаны навыки работы с javascript, которые я обычно получаю в своей практике, изучаю в блогах и встречаю в исходном коде некоторых проектов. О некоторых вещах можно сказать, что это странные трюки, а некоторые могут быть более практичным новым синтаксисом в ES6+.
Использование && и ||
Иногда нам нужно выполнить другую функцию, когда функция или переменная истинны. Например:
const task1 = () => {
console.log('执行 task1');
return Math.random() >= 0.5;
}
const task2 = () => console.log('task1 执行成功后执行 task2');
if (task1()) task2();
Приведенный выше оператор if может быть использован&&Прямо сокращенно:
task1() && task2();
Если вы также выполняете задачу CADEC3 PADUCT1 после отказа (то есть Task1 возвращают false), вы можете использовать:
const task3 = () => console.log('task1 执行失败后执行 task3');
task1() && task2() || task3();
По сути, все еще использую&&а также||характеристики короткого замыкания.
На самом деле здесь тоже можно использовать условные операторы:
task1() ? task2() : task3();
Одно из моих последних применений показано нижеreact hooksФрагмент кода из разработанного проекта, который используется здесьrender props:
const ProfileItem = (props) => {
const { name, value, render } = props;
return (
<div className="profile-item">
<span className="item-name">{name}</span>
<form action="">
{/* 根据是否有 render 这个 props 来返回不同的内容 */}
{render && render(props) || <SimpleProfileItemContent value={value}/>}
</form>
</div>
)
}
значение функции по умолчанию
версия ES5
На самом деле довольно часто используется короткое замыкание или оператор для установки значения функции по умолчанию. Но есть некоторые подводные камни.В коде, показанном ниже, когда параметр значения по умолчанию является числом, значение по умолчанию будет по-прежнему использоваться, когда параметр передается как 0. Это должно оцениваться отдельно, когда y равно 0.
const pow = (x, y) => {
y = y || 2;
let result = 1;
for (let i = 0, max = y; i < max; i++) {
result *= x;
}
return result;
}
console.log(pow(2)); // => 4
console.log(pow(2, 3)); // => 8
// 当 y 传值为 0 时, y 取值 2
console.log(pow(2, 0)); // => 4
версия ES6
Синтаксис значения по умолчанию, предоставляемый ES6 на уровне синтаксиса, намного надежнее.
const pow = (x, y=2) => {
let result = 1;
for (let i = 0, max = y; i < max; i++) {
result *= x;
}
return result;
}
console.log(pow(2)); // => 4
console.log(pow(2, 3)) // => 8
console.log(pow(2, 0)); // => 1
массив-подобный массиву
Подобный массиву относится к чему-то вродеarguments,jqueryК объектам также можно получить доступ с помощью нижних индексов, и они имеют свойство длины класса объектов, которые похожи на массивы, но не на них.
массивный нетslice, mapи другие функции сбора, поэтому иногда нам нужно преобразовать массивы, подобные массивам, в массивы.
function func() {
for (let i = 0, max = arguments.length; i < max; i++) {
console.log(arguments[i]);
}
console.log(Array.isArray(arguments)); // => false
// 类数组没有 slice, forEach, map 等集合函数
console.log(arguments.slice === undefined); // => true
}
func('Google', 'facebook', 'Microsoft');
// =>
// Google
// facebook
// Microsoft
Методы преобразования в ES5
Привяжите метод slice в прототипе Array к объекту arguments и вызовите его без передачи аргументов, чтобы он возвращал все элементы.
function func() {
const array = Array.prototype.slice.call(arguments);
console.log(array.slice(0, 1));
}
func('Google', 'facebook', 'Microsoft'); // => [ 'Google' ]
Методы преобразования в ES6
В ES6 есть больше способов конвертировать массивы в массивы.
Использовать оператор спреда
function func() {
console.log([...arguments])
}
func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ]
Используйте Array.from
function func() {
console.log(Array.from(arguments))
}
func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ]
Создает массив последовательных целых чисел
Вот что я думаю, это лучший способ
// 输出 2 开始连续的8个整数
const array = Array.from({ length: 8}).map((ele, index) => index + 2);
console.log(array); // => [ 2, 3, 4, 5, 6, 7, 8, 9 ]
// 评论区指出有更简洁的版本, Array.from 自带的映射函数
const array = Array.from({ length: 8}, (ele, index) => index + 2);
console.log(array); // => [ 2, 3, 4, 5, 6, 7, 8, 9 ]
// 还有一个网友指出可以利用 Array.prototype.keys 来构造
const array = [...Array(8).keys()].map((ele, index) => index + 2)
Назначение деструктурирования для параметров функции
Когда есть много параметров функции, мы часто позволяем параметрам напрямую принимать объект конфигурации. Однако мы не можем устанавливать значения по умолчанию при использовании параметров объекта.При использовании параметров объекта в теле функции нам также необходимо использовать параметры объекта для доступа.При большом количестве посещений или глубокой вложенности это будет неудобно . Использование деструктурирующего присваивания в параметрах функции решает указанную выше проблему.
// 必须给对象参数设置默认值, 不然传参数时因为没有解构对象会报错
const getUsers = ({
offset=0,
limit=1,
orderBy="salary"
}={}) => {
// 根据条件查询数据库返回用户数据
console.log({ offset, limit, orderBy });
}
getUsers({ offset: 10, limit: 20,orderBy: 'age' }); // => { offset: 10, limit: 20, orderBy: 'age' }
getUsers();// => { offset: 0, limit: 1, orderBy: 'salary' }
Использовать!!Преобразование других типов в тип BOOL
console.log(!!{}); // true
console.log(!!0); // false
console.log(!![]); // true
console.log(!!undefined); // false
const httpGet = (url, retry) => {
if (!!retry) {
// 超时重发
}
}
JSON.stringify
глубокий клон
Обычно для глубокого клонирования объектов удобно использовать метод сначала сериализации, а затем десериализации, недостатком является невозможность клонирования функций и унаследованных свойств.
Если вы также хотите клонировать свойства функции, рекомендуется использовать cloneDeep от lodash.
const me = {
name: 'lyreal666',
age: 23,
speak() {
console.log(`Hello, I'm ly!`);
}
}
const clonedMe = JSON.parse(JSON.stringify(me));
console.log(clonedMe); // => { name: 'lyreal666', age: 23 }
console.log(clonedMe.speak === undefined); // => true
Используйте второй и третий аргументы
Второй параметр JSON.stringify используется для обработки значения атрибута, а третий параметр используется для указания длины отступа выходной строки json, которой может быть передано число или строка.
const me = {
name: 'lyreal666',
age: 23,
speak() {
console.log(`Hello, I'm ly!`);
}
}
const jsonStr = JSON.stringify(me, (key, value) => key === 'name' ? '老余' : value, 2);
console.log(jsonStr);
/* =>
{
"name": "老余",
"age": 23
}
*/
элегантно перебирать объекты
Используйте присваивание деструктурирования и Object.entries.
const me = {
name: 'lyreal666',
age: 23,
speak() {
console.log(`Hello, I'm ly!`);
}
}
for (const [key, value] of Object.entries(me)) {
console.log(`${key}: ${value}`);
}
/* =>
name: lyreal666
age: 23
speak: speak() {
console.log(`Hello, I'm ly!`);
}
*/
Самый быстрый способ очистить массив
Кто-то в области комментариев сказал, что это своего рода прямая модификацияlengthПодход проблематичный, раньше видел обсуждения метода очистки массива, но думаю, что в целом его использовать не проблема, он простой и не требует перераспределения памяти под новый массив.
const array = [1, 2, 3, 4];
array.length = 0;
console.log(array); // => []
// 网友指出可以更好的方式是直接赋值空数组
let array = [1, 2, 3, 4];
array = [];
Проверить, является ли целое число -1
// ~ 操作符的运算规律可以简单记作将加一的结果取反
console.log(~1); // => -2
console.log(~0); // => -1
console.log(~(-3)); // => 2
console.log(~(-1)); // => 0
const number = -2;
// 判断一个数是否为 -1
if (!~number) {
// 当 number 是 -1 的操作...
}
выполнить функцию немедленно
Немедленное выполнение функции позволяет переменным в нашем коде не загрязнять внешние переменные, и обычное использование выглядит следующим образом.
// 使用括号将函数括起来调用
(function(window, $) {
// 内部代码
}) (window, jQuery)
Более элегантным способом является следующий, на самом деле многие другие арифметические операторы, такие как +, -, *, ~ и т. д., также возможны.
! function(window, $) {
// 内部代码
} (window, jQuery)
// 还可以使用 +, -, * 等
+ function(window, $) {
// 内部代码
} (window, jQuery)
// 更神奇的是还可以用 new, typeof 等操作符
new function(window, $) {
// 内部代码
} (window, jQuery);
Используйте set для дедупликации массива
console.log([...new Set([1, 3, 1, 2, 2, 1])]); // => [ 1, 3, 2 ]
Используйте сокращение, чтобы умножить или добавить
const array = [ 1, 2, 3, 4];
// 连加
console.log(array.reduce((p, c) => p + c)); // => 10
// 连乘
console.log(array.reduce((p, c) => p * c)); // => 24
Округление
Множество функций округления в математике здесь обсуждаться не будет, в основном для того, чтобы упомянуть некоторые более умные методы округления.
console.log(~~3.14); // => 3
console.log(~~(-2.5)); // => -2
console.log(6.18 | 0); // => 6
console.log(-3.6 | 0); // => -3
console.log(9.9 >> 0); // => 9
console.log(-2.1 >> 0); // => -2
// superagent 是一个很实用的发送 http 请求的 node 模块,它对返回码的处理就用到了 |
var type = status / 100 | 0;
// status / class
res.status = status;
res.statusType = type;
// basics
res.info = 1 == type;
res.ok = 2 == type;
res.clientError = 4 == type;
res.serverError = 5 == type;
res.error = 4 == type || 5 == type;
Используйте + для преобразования других типов в числовой тип
console.log(+'3.14'); // => 3.14
console.log(typeof +'3.14') // => number
const sleep = (milliseconds) => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), milliseconds);
});
}
// 当然这里可以考虑使用 console.time 来测试
! async function main() {
const start = +new Date();
await sleep(3000);
const end = +new Date();
console.log(`执行了${end - start}`); // 执行了 3002
}();
Представление больших чисел с помощью экспоненциальной записи
const str1 = 'hello';
const str2 = ' world'
console.time('测试 + 拼接字符串');
for (let i = 0; i < 200000000; i++) {
const joinedStr = str1 + str2;
}
console.timeEnd('测试 + 拼接字符串');
console.time('测试模板字符串拼接字符串');
// 使用科学计数法比打 8 个 0 方便不少
for (let i = 0; i < 2E8; i++) {
const joinedStr =`${str1}${str2}`;
}
console.timeEnd('测试模板字符串拼接字符串')
/* =>
测试 + 拼接字符串: 3238.037ms
测试模板字符串拼接字符串: 3680.225ms
*/
Поменять местами значения переменных
Прямое использование деструктурирующего присваивания
let a = 666;
let b = 999;
[a, b] = [b, a];
console.log({ a, b }); // => { a: 999, b: 666 }
получить случайную строку
Строка после начала нижнего индекса 2 перехватывается, поскольку строка, состоящая из десятичных знаков, возвращаемых функцией Math.random(), не требуется.0.эти два персонажа. Использование базы 36 может создавать случайные строки с более широким набором символов.
console.log(Math.random().toString(16).substring(2)); // 13位 => 45d9d0bb10b31
console.log(Math.random().toString(36).substring(2)); // 11位 => zwcx1yewjvj
сглаженный массив
ES 2019 добавил Array.prototype.flat, в настоящее время поддерживается последняя официальная версия chrome 73.0.3683.103, последняя LTS 10.15.3 узла еще не поддерживается, а поддерживается последняя версия разработки узла 11.13.0. Вот сравнительный метод взлома, замеченный в братстве Наггетов, Здесь мы должны обратить внимание на преобразование типов в зависимости от ситуации.
const array = [1, [2, [3, 4], 5], 6, 7];
console.log(array.toString().split(',').map(ele => Number.parseInt(ele))); // => [ 1, 2, 3, 4, 5, 6, 7 ]
Недавно я брал интервью у Tencent, и положение Али на стажировке переднего плана действительно трудно описать. Я планирую рассказать о своем недавнем опыте собеседования во всей статье позже. Nodejs вот-вот закончит вторую статью из серии краулеров.
Эта статья представляет собой оригинальный контент, впервые опубликованный вличный блог, Пожалуйста, укажите источник. Если у вас есть какие-либо вопросы, пожалуйста, напишите ytj2713151713@gmail.com.