文章目录
- 前言
- 一、工具函数所在目录
- 二、判定数据类型的函数
- 1.isArray(判定数组)
- 2.isString(判定字符串)
- 3.isNumber(判定数值)
- 4.isObject(判定对象)
- 5.isPlainObject(判定纯对象)
- 6.isUndefined(判定是否是undefined)
- 7.isFunction(判定是否是Function)
- 8.isDate(判定是否是Date对象)
- 9.isFile(判定是否是File文件对象)
- 10.isBlob(判定是否是Blob对象)
- 11.isBuffer(判定是否是Buffer对象)
- 12.isArrayBuffer(判定是否是ArrayBuffer对象)
- 13.isFormData(判定是否是FormData对象)
- 14.isStream(判定是否是Stream)
- 15.isURLSearchParams(判定是否是URLSearchParams对象)
- 三、其他常用的工具方法
- 1.trim(去除首尾空格)
- 2.isStandardBrowserEnv(判定标准浏览器环境)
- 3.forEach(遍历对象或数组)
- 4.merge(合并对象)
- 5.extend(对象属性扩展)
- 6.stripBOM(删除UTF-8编码中BOM)
- 总结
前言
学习源码,可以帮助我们工具基础知识点和提升编程能力。之前分享过vue3中的常用工具函数(戳此链接)。
那今天本文的主角是axios源码中的/lib/utils.js,介绍一下axios库中常用的工具函数
一、工具函数所在目录
axios/lib/utils.js
二、判定数据类型的函数
共用的toString 方法
var toString = Object.prototype.toString;
1.isArray(判定数组)
和vue3源码中判定一样
function isArray(val) {
return Array.isArray(val);
}
2.isString(判定字符串)
function isString(val) {
return typeof val === 'string';
}
3.isNumber(判定数值)
function isNumber(val) {
return typeof val === 'number';
}
4.isObject(判定对象)
注意在js中,null
也是一个特殊对象,此时判定要排出null的情况。
此方法同vue3源码中判定对象方法
function isObject(val) {
return val !== null && typeof val === 'object';
}
5.isPlainObject(判定纯对象)
纯对象: 用{}或new Object()创建的对象。
此方法同vue3源码中判定纯对象方法
function isPlainObject(val) {
if (toString.call(val) !== '[object Object]') {
return false;
}
var prototype = Object.getPrototypeOf(val);
return prototype === null || prototype === Object.prototype;
}
测试代码如下
const o = {name: 'jay}
isPlainObject(o)
const o = new Object()
o.name = 'jay'
isPlainObject(o)
function C() {}
const c = new C()
isPlainObject(c);
6.isUndefined(判定是否是undefined)
function isUndefined(val) {
return typeof val === 'undefined';
}
7.isFunction(判定是否是Function)
function isFunction(val) {
return toString.call(val) === '[object Function]';
}
在vue3中该方法如下:
export const isFunction = (val: unknown) => typeof val === 'function'
两种方法比较:
- typeof 操作符返回一个字符串,表示右侧操作数的类型。对于函数来说,会返回字符串 “function”。这种方式适用于各种函数,例如命名的函数,赋值到变量的函数,箭头函数等。(不过需要注意:部分浏览器(例如在 Chrome 57 )存在 bug,对于 HTML 的 object 元素和 embed 元素上运行 typeof 会返回 “function”。)
- toString() 方法检查一个变量的类型,它会获得变量的字符串表现形式,然后和字符串 ‘[object Function]’进行比对。不过这种方式不可靠,不能正确识别 复制到变量的函数、 ES 6 的 class 和异步函数。
- 综合对比,优选typeof 方法判定function
测试代码如下:
let a = function(){console.log(1)};
console.log(typeof a);
console.log(Object.prototype.toString.call(a));
let b = function(){console.log(1)};
console.log(typeof b);
console.log(Object.prototype.toString(b));
class C{}
console.log(typeof C);
console.log(Object.prototype.toString.call(C));
8.isDate(判定是否是Date对象)
function isDate(val) {
return toString.call(val) === '[object Date]';
}
vue3中该方法如下:
export const isDate = (val: unknown) => val instanceof Date
两种方法对比:
- 首先判定Date,不能使用~~
typeof
~~ ,因为会返回object
- 我们通常创建一个Date对象,使用的是
new Date()
,通过new关键字创建的可以使用instanceof
(instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上)判定。同时toString方法也可以准确得到'[object Date]'
- 综上所述,以上两种方法均可
9.isFile(判定是否是File文件对象)
function isFile(val) {
return toString.call(val) === '[object File]';
}
10.isBlob(判定是否是Blob对象)
- Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取。
function isBlob(val) {
return toString.call(val) === '[object Blob]';
}
11.isBuffer(判定是否是Buffer对象)
- JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
- axios可以运行在浏览器和node环境中,所以内部会用到nodejs相关的知识
- 在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。
function isBuffer(val) {
return val !== null
&& !isUndefined(val)
&& val.constructor !== null
&& !isUndefined(val.constructor)
&& typeof val.constructor.isBuffer === 'function'
&& val.constructor.isBuffer(val);
}
测试代码如下:
const buf = Buffer.from([1, 2, 3]);
console.log(typeof buf)
console.log(buf instanceof Buffer);
console.log(buf.constructor.isBuffer(buf))
12.isArrayBuffer(判定是否是ArrayBuffer对象)
function isArrayBuffer(val) {
return toString.call(val) === '[object ArrayBuffer]';
}
13.isFormData(判定是否是FormData对象)
function isFormData(val) {
return toString.call(val) === '[object FormData]';
}
测试代码:
let form = new FormData();
form.append('namme',12);
Object.prototype.toString.call(form)
'[object FormData]'
14.isStream(判定是否是Stream)
- 这里
isObject
、isFunction
为上文提到的方法。 - 是对象,也是函数。就是流
function isStream(val) {
return isObject(val) && isFunction(val.pipe);
}
15.isURLSearchParams(判定是否是URLSearchParams对象)
function isURLSearchParams(val) {
return toString.call(val) === '[object URLSearchParams]';
}
测试代码如下
const paramsString = "name=mj&age=13"
const searchParams = new URLSearchParams(paramsString);
console.log(isURLSearchParams(searchParams))
三、其他常用的工具方法
1.trim(去除首尾空格)
function trim(str) {
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
}
2.isStandardBrowserEnv(判定标准浏览器环境)
- axios可运行在web worker、react-native中
- 但是官方已经不推荐使用这个属性navigator.product。
function isStandardBrowserEnv() {
if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
navigator.product === 'NativeScript' ||
navigator.product === 'NS')) {
return false;
}
return (
typeof window !== 'undefined' &&
typeof document !== 'undefined'
);
}
3.forEach(遍历对象或数组)
function forEach(obj, fn) {
if (obj === null || typeof obj === 'undefined') {
return;
}
if (typeof obj !== 'object') {
obj = [obj];
}
if (isArray(obj)) {
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
}
}
4.merge(合并对象)
function merge() {
var result = {};
function assignValue(val, key) {
if (isPlainObject(result[key]) && isPlainObject(val)) {
result[key] = merge(result[key], val);
} else if (isPlainObject(val)) {
result[key] = merge({}, val);
} else if (isArray(val)) {
result[key] = val.slice();
} else {
result[key] = val;
}
}
for (var i = 0, l = arguments.length; i < l; i++) {
forEach(arguments[i], assignValue);
}
return result;
}
5.extend(对象属性扩展)
- 将一个对象的方法和属性扩展到另外一个对象上,并为对象方法指定上下文(this指向)
- 遍历b,把b中所有属性赋值给a,并且若属性值为方法以及给出了上下文对象thisArg,则需要改变function的上下文对象。
function extend(a, b, thisArg) {
forEach(b, function assignValue(val, key) {
if (thisArg && typeof val === 'function') {
a[key] = bind(val, thisArg);
} else {
a[key] = val;
}
});
return a;
}
6.stripBOM(删除UTF-8编码中BOM)
- BOM(Byte Order Mark),字节顺序标记,出现在文本文件头部,Unicode编码标准中用于标识文件是采用哪种格式的编码,但它对于文件的读者来说是不可见字符。
- Unicode 规范定义,每一个文件的最前面分别加入一个表示编码顺序的字符,即BOM.
- UTF-8 是 Unicode 的实现方式之一。
严
的 Unicode码
是4E25
,UTF-8
编码是E4B8A5
,两者是不一样的。它们之间的转换可以通过程序实现。 - UTF-8是与字节顺序无关的,所以UTF-8编码文件通常要删除掉BOM
function stripBOM(content) {
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1);
}
return content;
}
总结
本文介绍了一些utils.js
中的非常实用的工具函数;相信通过阅读源码,日积月累,并把这些代码或思想应用的自己项目中去,相信能够很好的提升自己的编码能力。
- is开头的函数通常用来判断变量类型
- 引用类型的数据通常用Object.prototype.toString.call(val)===’[object Array]'来判断
- 基础数据类型,通常使用typeof去判断
- instanceof 运算符用于检测构造函数的
prototype
属性是否出现在某个实例对象的原型链上
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)