isFormData
判断是否是
FormData类型
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
val | any | 需要判断的值 |
实现
export function isFormData(val: any): val is FormData {
return typeof val !== 'undefined' && val instanceof FormData;
}
示例
const formData = new FormData();
formData.append('username', 'botaoxy');
formData.append('password', '123456');
isFormData(formData); // true
isEmptyObject
判断是否是
空对象
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
val | any | 需要判断的值 |
实现
export function isEmptyObject(val: any): boolean {
for (const key in val) {
return false;
}
return true;
}
示例
const obj = {};
isEmptyObject(obj); // true
const obj1 = {
userName: 'botaoxy',
password: '123456'
}
isEmptyObject(obj); // false
isPlainObject
判断是否是
普通对象
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
val | any | 需要判断的值 |
实现
export function isPlainObject(val: any): val is Object {
return Object.prototype.toString.call(val) === '[object Object]';
}
示例
const obj = {};
isPlainObject(obj); // true
const obj1 = new Date();
isPlainObject(obj1); // false
debounce
防抖函数
wait毫秒后在执行该事件,若wait毫秒内被重复触发,则重新计时
- 搜索框输入搜索请求
- 手机号、邮箱等表单验证输入检测
- 窗口大小
resize,只需窗口调整完成后,计算窗口大小。防止频繁渲染。
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
fn | any | 指定的函数 |
wait | number | 防抖时间(毫秒) |
immediate | boolean-默认值false | 是否立即执行 |
实现
export function debounce(fn: any, wait: number, immediate: boolean = false) {
let timer: ReturnType<typeof setTimeout> | null;
const lambda = function (this: any) {
const args = Array.prototype.slice.call(arguments);
if (timer) clearTimeout(timer as ReturnType<typeof setTimeout>);
// 立即执行
if (immediate) {
const callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait);
if (callNow) {
fn.apply(this, args);
}
} else {
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
}
};
// 取消功能
lambda.cancel = function () {
clearTimeout(timer as ReturnType<typeof setTimeout>);
timer = null;
};
return lambda;
}
示例
const dom = document.getElementById('container');
function mouseMove(event){
console.log(this, event);
dom.innerHTML = `${event.clientX}-${event.clientY}`
}
dom.onmousemove = debounce(mouseMove, 1000);
throttle
节流函数
wait毫秒内只运行一次,若wait毫秒内重复触发,只有一次生效
- 滚动加载
- 搜索框联想功能
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
fn | any | 指定的函数 |
wait | number | 节流时间(毫秒) |
options | {leading?: boolean;trailing?: boolean;} | 节流配置参数 |
| 属性 | 说明 | 默认值 |
|---|---|---|
leading | 是否立即执行 | false |
trailing | 调用结束后是否再执行一次 | true |
实现
export function throttle(
fn: any,
wait: number,
options: {
leading?: boolean;
trailing?: boolean;
} = {}
) {
let previous = 0;
let timer: ReturnType<typeof setTimeout> | null;
const defaultOpts = Object.assign(
{
leading: false,
trailing: true,
},
options
);
const lambda = function (this: any) {
const now = Date.now();
const args = Array.prototype.slice.call(arguments);
if (!previous && !defaultOpts.leading) previous = now;
const remaining = wait - (now - previous);
if (remaining <= 0 || remaining > wait) {
if (timer) {
clearTimeout(timer);
timer = null;
}
previous = now;
fn.apply(this, args);
if (!timer) args = null;
} else if (!timer && defaultOpts.trailing) {
timer = setTimeout(() => {
previous = defaultOpts.leading === false ? 0 : Date.now();
timer = null;
const args = Array.prototype.slice.call(arguments);
fn.apply(this, args);
if (!timer) args = null;
}, remaining);
}
};
// 取消功能
lambda.cancel = function () {
clearTimeout(timer as ReturnType<typeof setTimeout>);
timer = null;
previous = 0;
};
return lambda;
}
示例
function getUserInfo() {
// 请求接口获取数据
return axios
.post('/user', { userName: 'botaoxy', password: '123456' })
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
throttle(getUserInfo, 1000);
isURLSearchParams
判断是否是
URLSearchParams
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
val | any | 需要判断的值 |
实现
export function isURLSearchParams(val: any): val is URLSearchParams {
return typeof val !== 'undefined' && val instanceof URLSearchParams;
}
示例
const paramsString = "q=URLUtils.searchParams&topic=api";
const searchParams = new URLSearchParams(paramsString);
isURLSearchParams(searchParams); //true
encodeURIC
URI针对特殊字符编码处理
实现
export function encodeURI(val: string): string {
return encodeURIComponent(val)
.replace(/%40/g, '@')
.replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%20/g, '+')
.replace(/%5B/gi, '[')
.replace(/%5D/gi, ']');
}
示例
console.log(`?x=${encodeURI('botaoxy?')}`); // ?x=botaoxy%3F
console.log(`?x=${encodeURI('шеллы')}`); // "?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
buildURL
构建
url
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
url | string | url地址 |
params | any | url参数 |
paramsSerializer | (params: any) => string | 自定义参数序列化 |
实现
依赖函数
⌈前端工具函数⌋❤️🔥第一弹❤️🔥 - 掘金 (juejin.cn)-typeOf
isURLSearchParams- 判断是否是 **URLSearchParams**类型
encodeURIC-encodeURIComponent针对一些特殊字符编码处理
export function buildURL(url: string, params?: any, paramsSerializer?: (params: any) => string) {
if (!params) return url;
let serializerParams;
if (paramsSerializer) {
serializerParams = paramsSerializer(params);
} else if (isURLSearchParams(params)) {
serializerParams = params.toString();
} else {
const parts: string[] = [];
Object.getOwnPropertyNames(params).forEach((key) => {
const paramsVal = params[key];
if (paramsVal === null || typeof paramsVal === 'undefined') return;
let values = [];
if (typeOf(paramsVal) === 'array') {
values = paramsVal;
key += '[]';
} else {
values = [paramsVal];
}
values.forEach((val: any) => {
if (typeOf(val) === 'date') {
val = val.toISOString();
} else if (typeOf(val) === 'object') {
val = JSON.stringify(val);
}
parts.push(`${encodeURIC(key)}=${encodeURIC(val)}`);
});
});
serializerParams = parts.join('&');
}
if (serializerParams) {
const markIndex = url.indexOf('#');
if (markIndex !== -1) {
url = url.slice(0, markIndex);
}
url += (url.indexOf('?') === -1 ? '?' : '&') + serializerParams;
}
return url;
}
示例
// 传入 url 和 对象参数
const url = 'https://127.0.0.1/search';
const params = {
userName: 'botaoxy',
password: '123456'
}
buildURL(url, params); // https://127.0.0.1/search?userName=botaoxy&password=123456
// 传入的 URLSearchParams 类型的参数
const paramsString = "userName=botaoxy&password=123456";
const searchParams = new URLSearchParams(paramsString);
buildURL(url, searchParams); // https://127.0.0.1/search?userName=botaoxy&password=123456
// url已携带部分参数来做组合
const url1 = 'https://127.0.0.1/search?userName=botaoxy';
const params1 = {
password: '123456'
}
buildURL(url1, params1); // https://127.0.0.1/search?userName=botaoxy&password=123456
parseURL
解析
url参数
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
url | string | url地址 |
实现
export function parseURL(url: string) {
const instanceURL = new URL(url);
const URLParams = instanceURL.search.slice(1);
if (!URLParams) return null;
const splitURLParams = URLParams.split('&');
const params = Object.create(null);
splitURLParams.forEach((param) => {
if (param.includes('=')) {
const [key, val] = param.split('=');
params[key] = decodeURIComponent(val);
} else {
params[param] = true;
}
});
return params;
}
示例
const url = 'https://127.0.0.1/search?serName=botaoxy&password=123456';
parseURL(url);
// {
// userName: 'botaoxy',
// password: '123456'
// }
jsonp
使用
script的src属性实现跨域
| 参数名 | 参数类型 | 参数说明 |
|---|---|---|
url | string | url地址 |
callbackName | string-默认值callback | 回调函数名 |
params | any | url参数 |
paramsSerializer | (params: any) => string | 自定义参数序列化 |
实现
依赖函数
buildURL- 构建URL
interface JsonpOpts {
url: string;
callbackName: string;
params?: any;
paramsSerializer?: (params: any) => string;
}
export function jsonp(options: JsonpOpts) {
const { url, callbackKey='callback', callbackName, params, paramsSerializer } = options;
return new Promise((resolve, reject) => {
const scriptEl = document.createElement('script');
scriptEl.src = `${buildURL(url, params, paramsSerializer)}&${callbackKey}=${callbackName}`;
document.body.appendChild(scriptEl);
(<any>window)[callbackName] = (data: any) => {
resolve(data);
document.removeChild(scriptEl);
};
});
}
示例
jsonp({
url: 'http://127.0.0.1/search?wd=botaoxy',
callbackKey: 'cb',
callbackName: customFun
}).then(res=>{
console.log(res)
})
// async await
async function searchUser(){
const userInfo = await jsonp({
url: 'http://127.0.0.1/search?wd=botaoxy',
callbackKey: 'cb',
callbackName: customFun
})
}
后记
个人博客 | Botaoxy (chengbotao.github.io)
chengbotao (Chengbotao) (github.com)
billows - npm
chengbotao/billows: 使用 TypeScript 收集总结常用的工具函数
感谢阅读,敬请斧正!
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。