Пишите повторно используемые функции как профессионал.
В этой статье я покажу вам несколько замечательных служебных функций в Vue3, их исходный код находится здесь. Эти функции можно многократно использовать и они полезны для повседневной разработки, так что давайте начнем!
1. Определите, начинается ли строка с on
const onRE = /^on[^a-z]/; const isOn = (key: string) => onRE.test(key); console.log(isOn('onClick')); // true console.log(isOn('onclick')); // false
Вы можете видеть, что он использует обычное сопоставление. Он будет соответствовать буквам, начинающимся с on
и чьим следующим символом является не a
до z
.
2. Определение того, является ли свойство собственным
const hasOwnProperty = Object.prototype.hasOwnProperty; const hasOwn = (val: object, key: string | symbol): key is keyof typeof val => hasOwnProperty.call(val, key); const testObj = { name: 1 }; console.log(hasOwn(testObj, 'name')); // true Object.getPrototypeOf(testObj).age = 2; console.log(hasOwn(testObj, 'age')); // false
Этот метод использует Object.prototype.hasOwnProperty
, чтобы определить, является ли ключ свойством самого объекта.
Когда мы используем Object.getPrototypeOf()
для получения прототипа testObj и устанавливаем для него свойство age, hasOwn вернет false.
Помимо прочего, здесь используется ключевое слово TypeScript is
, которое создает определяемую пользователем защиту типа, которая проверяет во время выполнения, чтобы убедиться, что это тот тип, который мы ожидаем в определенной области. Если вы не уверены в этом, посмотрите мою предыдущую статью.
3. Определите, является ли это обещанием
const isObject = (val: unknown): val is Record<any, any> => val !== null && typeof val === 'object'; const isFunction = (val: unknown): val is Function => typeof val === 'function'; const isPromise = <T = any>(val: unknown): val is Promise<T> => { return isObject(val) && isFunction(val.then) && isFunction(val.catch); }; console.log(isPromise(new Promise(() => {}))); // true console.log(isPromise(async function () {})); // false console.log(isPromise(function* () {})); // false
Этот метод заимствует isObject
, чтобы определить, что текущее значение является объектом, и isFunction
, чтобы определить, что свойства then
и catch
текущего значения являются функциями.
Все три из них также используют ключевое слово is
. Кроме того, isPromise
также использует дженерики для передачи типа Result Promise.
4. Определите, является ли это целочисленной строкой
const isString = (val: unknown): val is string => typeof val === 'string'; const isIntegerKey = (key: unknown) => isString(key) && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key; console.log(isIntegerKey('10')); // true console.log(isIntegerKey('010')); // false console.log(isIntegerKey('3.0')); // false console.log(isIntegerKey('Vue')); // false
Сначала используйте isString
, чтобы определить, является ли это строковым типом, затем оцените, является ли это 'NaN'
, а первый символ не -
, и, наконец, используйте пустую строку для преобразования десятичного числа, преобразованного с помощью parseInt
, в строку, чтобы определить, равно ли оно исходная строка.
5. Результаты расчета строки кэша
const cacheStringFunction = <T extends (str: string) => string>(fn: T): T => { const cache: Record<string, string> = Object.create(null); return ((str: string) => { const hit = cache[str]; return hit || (cache[str] = fn(str)); }) as any; }; const getUpperCase = cacheStringFunction((str: string): string => str.toUpperCase(), ); console.log(getUpperCase('a')); // A console.log(getUpperCase('a')); // A
Это функция более высокого порядка, которая использует внутреннее замыкание для кэширования предыдущего результата вычисления и возвращает предыдущий результат, если обнаруживается, что он был вычислен при повторном вызове.
6. Дефис в CamelCase / CamelCase в дефис
const cacheStringFunction = <T extends (str: string) => string>(fn: T): T => { const cache: Record<string, string> = Object.create(null); return ((str: string) => { const hit = cache[str]; return hit || (cache[str] = fn(str)); }) as any; }; const camelizeRE = /-(\w)/g; const camelize = cacheStringFunction((str: string): string => { return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); }); const hyphenateRE = /\B([A-Z])/g; const hyphenate = cacheStringFunction((str: string) => str.replace(hyphenateRE, '-$1').toLowerCase(), ); console.log(camelize('on-click')); // onClick console.log(camelize('test-a-click')); // testAClick console.log(hyphenate('onClick')); // on-click console.log(hyphenate('testAClick')); // test-a-click
Вышеупомянутые два метода используют регулярные выражения для сопоставления и используют String.prototype.replace()
для замены символов, и они обертываются функцией кеша, представленной в предыдущем разделе, что означает, что когда одна и та же строка должна быть обработана, она будет непосредственно возвращена в кеш. Результаты.
7. Получить глобальный объект текущей среды
let _globalThis: any; const getGlobalThis = (): any => { return ( _globalThis || (_globalThis = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {}) ); }; console.log(getGlobalThis()); console.log(getGlobalThis());
Здесь также используется замыкание, но на этот раз _globalThis
, хранимое замыканием, находится в загруженном в данный момент модуле, так что его нужно вызвать и оценить только один раз, а последующие оценки не требуются.
Давайте посмотрим на логику внутри функции, ее приоритет:
- Используйте globalThis, который обеспечивает стандартный способ доступа к глобальному объекту в разных средах.
- Судя по я, это потому, что в Веб-воркерах к оконному объекту нельзя получить доступ, а к текущему глобальному объекту можно получить доступ только через я.
- Общие оконные объекты.
- Глобальный объект в Node.js.
На сегодня все. Меня зовут Закари, и я буду продолжать публиковать истории, связанные с веб-разработкой. Если вам нравятся такие истории и вы хотите поддержать меня, рассмотрите возможность стать членом Medium. Это стоит 5 долларов в месяц и дает вам неограниченный доступ к контенту Medium. Я получу небольшую комиссию, если вы зарегистрируетесь по моей ссылке.
Ваша поддержка очень важна для меня — спасибо.
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Присоединяйтесь к нашему сообществу Discord.