本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
- 判断是否为数组
* 用Array.isArray判断是否是数组
* 也可使用Object.prototype.toString.call(params),判断对象的类型
* @param {Object} val
* @returns {Boolean}
*/
function isArray(val) {
return Array.isArray(val)
}
var arr = [1, 2, 3]
console.log(isArray(arr)); //true;
- 判断是否为undefined,用typeof和全等判断
/**
* @param {Object} val
* @returns {Boolean}
*/
function isUndefined(val) {
return typeof val === 'undefined'
}
console.log(isUndefined(2)); //false
console.log(isUndefined(undefined));//true;
- 判断是否为buffer(二进制数据的缓存区),它是一个类
/**
* 1. 判断参数是否为underfined和null
* 2. 判断buffer是否存在构造函数
* 3. 用buffer下面的方法判断参数是否为buffer
* @param {Object} val
* @returns {Boolean}
*/
function isBuffer(val) {
return val !== null &&
!isUndefined(val) &&
val.constructor !== null &&
!isUndefined(val.constructor) &&
typeof val.constructor.isBuffer === 'function' &&
val.constructor.isBuffer(val)
}
var a = Buffer.alloc(10)
console.log('a: ', a);
console.log(isBuffer(a));//true;
- 判断是否为对象
/**
*
* 先判断它是否为null,因为typeof判断null也为对象.
* 不是则判断它是否为对象
*
*/
function isObject(val) {
return val !== null && typeof val === 'object'
}
-
let toString = Object.prototype.toString;,将toString函数提取出来作为公共函数,这一点和vue2的工具函数很像 -
判断是否为函数
function isFunction(val){
return toString.call(val) ==='[object Function]'
}
let d = function t(){}
console.log('isFunction',isFunction(d));//true;
- 判断是否为FormData的实例
/**
* 判断是否为FormData的实例
* instanceof 用于判断构造函数的prototype是否在某个实例的原型链上
* 1. 判断参数是否存在
* 2. 判断FormData是否为函数且FormData的prototype是否在参数的原型链上
* 3. 用Object.prototype.toString判断参数类型
* 4. 判断参数的toString是否为函数并且调用后是否为'[object FormData]'
* Object.getPrototypeOf(params)获取对象的原型
* isPrototypeOf(params),判断一个对象是否在另一个对象的原型链上
* toString返回一个对象的字符串形式
* @param {*} thing
* @returns {Boolean}
*/
function isFormatData(thing){
var pattern = '[object FormData]';
return thing&&(typeof FormData === 'function'&&thing instanceof FormData||
toString.call(thing)===pattern ||
(isFunction(thing.toString)&& thing.toString()===pattern))
}
- 类型判断帮助函数,它是一个自执行函数,默认的参数为一个没有原型的空object
/**
* 类型判断帮助函数,它是一个自执行函数,默认的参数为一个没有原型对象
* 利用toString获取对象的字符串形式
* 当参数对象里有以这个字符串为key的value,返回这个value
* 否则则设置以这个字符串为key的value,然后返回
* */
var kindOf = (function(cache){
return function(thing){
var str = toString.call(thing);
return cache[str] || (cache[str] = str.slice(8,-1).toLowerCase())
}
})(Object.create(null))
let j = {a:1}
console.log('kindOf(j)',kindOf(j)); //object;
- 判断是否是{}或new Object出来的对象,非日期,正则对象
/**
* 用类型帮助函数判断参数的类型
* 然后判断参数的原型是否为null或者为Object.prototype
* @param {*} val
* @returns {Boolean}
*/
function isPlainObjct(val){
if(kindOf(val)!=='object'){
return false;
}
var prototype = Object.getPrototypeOf(val);
return prototype ===null || prototype===Object.prototype
}
function C(){};
let c = new C();
console.log(isPlainObjct(c));
- 类型匹配帮助函数(
kindof)的进一步封装,传入的参数即为默认需判断的对象类型,返回一个判断与该对象类型是否匹配的函数
/**
* @param {*} type 预设的对象类型
* @return {Boolean}
*/
function kindOfTest(type){
type = type.toLowerCase();
return function isKindOf(thing){
return kindOf(thing) === type
}
}
- isDate是kindOfTest返回的函数,用来判断是否为日期类型
var isDate = kindOfTest('Date')
var k = isDate('1122')
console.log('k: ', k); //false;
- isFile是kindOfTest返回的函数,用来判断是否为文件类型
var isFile = kindOfTest('File')
- isBlob是kindOfTest返回的函数,用来判断是否为Blob类型
var isBlob = kindOfTest('Blob')
- isURLSearchParams是kindOfTest返回的函数,用来判断是否为URLSearchParams类型,它用来处理url查询字符串的
var isURLSearchParams= kindOfTest('URLSearchParams')
- 判断是否为二进制流
/**
*
* 1. 先判断val是否为对象
* 2. 再判断val.pipe是否为函数
* @param {*} val
* @returns {Boolean}
*/
function isStream(val){
return isObject(val) && isFunction(val.pipe)
}
- 去除字符串左右两边的空格
/**
*
* 1. 存在trim方法,则使用trim方法
* 2. 否则用正则配合replace方法去除空格
* @param {string} str
* @returns {string}
*/
function trim(str){
return str.trim? str.trim():str.replace(/^\s+|\s+$/g,'')
}
let str = ' 1234 '
console.log(trim(str).length); //4;
- 判断是否是在标准的浏览器环境
/**
* 让axios能在web worker和react-native环境里使用
*/
function isStandardBrowserEnv(){
if(typeof navigator!=="undefined"
&&(navigator.product==='ReactNative'||
navigator.product==="NativeScript"||
navigator.product ==="NS")){
return false;
}
return (
typeof window !=='undefined'&&
typeof document !=='undefined'
)
}
console.log('isStandardBrowserEnv',isStandardBrowserEnv());//在浏览器环境下返回true
- 实现一个对数组和对象都能迭代的forEach
function forEach(obj,fn){
// 如果obj为假值,则直接返回
if(obj==null || typeof obj ==='undefined'){
return
}
//如果obj不是对象,则将其转化成数组
if(typeof obj!=='object'){
obj =[obj]
}
// 如果是数组,用for循环迭代
if(isArray(obj)){
for (var i = 0; i < obj.length; i++) {
fn.call(null,obj[i],i,obj)
}
}else{
// 如果是对象的话,用for in迭代,并且只迭代自身有的值
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj,key)) {
fn.call(null,obj[i],key,obj)
}
}
}
}
forEach([1,2,3],function(item,i,arr){
console.log('item: ', item,i,arr);
})
- 移除BOM
/**
* 移除字节顺序标记(BOM),BOM出现在文件头部,在Unicode中指定文件的编码
* UTF-8中是不需要这个BOM的,它是单字节的,顺序对UTF-8是不那么重要的
*/
function stripBOM(content){
if(content.chrCodeAt(0)===0xFEFF){
content = content.slice(1)
}
return content;
}
-
关于BOM的参考资料 1. docs.microsoft.com/en-us/globa… 2. [blog.csdn.net/weixin_3964…
-
总结:
- axios的注释,第一行一般说明函数的作用,可能会附带一些对这个函数的说明,第二行一般是说明传入参数的类型及参数本身,第三行一般是说明返回的类型。感觉这样看到这个函数你就能清晰的知道这个函数的作用、参数及返回值。平常写代码也可以借鉴。
- vue2和axios的工具函数看代码,都喜欢用
Object.prototype.toString来判断对象的类型。不同的是它俩根据自身的目的进行不同的封装 - axios的工具函数就像乐高积木一样,一块小的功能结合其他功能就能构造出一个更大的功能。比如kindOfTest就是用kindOf构建起来的。这种思路可以借鉴。