vue2源码中用的工具类方法
// 未定义的
function isUndef(v) {
return v === undefined || v === null;
}
// 已定义的
function isDef(v) {
return v !== undefined && v !== null;
}
function isTrue(v) {
return v === true;
}
function isFalse(v) {
return v === false;
}
// 检查value是否为基本类型
function isPrimitive(value) {
return (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "symbol" ||
typeof value === "boolean"
);
}
// 判断是否是非null的对象
function isObject(obj) {
return obj !== null && typeof obj === "object";
}
// 利用 toString() 检测对象类型
// JavaScript 1.8.5 开始,toString() 调用 null 返回[object Null],undefined 返回 [object Undefined]
const _toString = Object.prototype.toString;
function toRawType(value) {
return _toString.call(value).slice(8, -1);
}
// 是否是纯对象
// 利用 toString(), 检测是否是严格意义的对象类型(非null的对象)
function isPlainObject(obj) {
return _toString.call(obj) === "[object Object]";
}
// 是否是正则表达式
// 利用 toString(), 检测是否是严格意义的RegExp
function isRegExp(v) {
return _toString.call(v) === "[object RegExp]";
}
// 检测val是否是一个有效的数组索引
function isValidArrayIndex(val) {
const n = parseFloat(String(val));
return n >= 0 && Math.floor(n) === n && isFinite(val);
}
// 检测是否是Promise
function isPromise(val) {
return (
isDef(val) &&
typeof val.then === "function" &&
typeof val.catch === "function"
);
}
// 将值转换为正真的字符串
function toString(val) {
return val == null
? ""
: Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
? JSON.stringify(val, null, 2)
: String(val);
}
// 转换为数字
function toNumber(val) {
const n = parseFloat(val);
return isNaN(n) ? val : n;
}
// 创建一个映射并返回一个函数,用于检查该映射中是否有一个键。
function makeMap(str, expectsLowerCase) {
const map = Object.create(null);
const list = str.split(",");
for (let i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase ? (val) => map[val.toLowerCase()] : (val) => map[val];
}
// 检查标签是否为内置标签。
const isBuiltInTag = makeMap("slot,component", true);
// 检查属性是否为保留属性。
const isReservedAttribute = makeMap("key,ref,slot,slot-scope,is");
// 从数组中移除一项
function remove(arr, item) {
if (arr.length) {
const index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1);
}
}
}
// 检查对象是否具有该属性。
const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key);
}
// 创建纯函数的缓存版本
function cached(fn) {
const cache = Object.create(null);
return function cachedFn(str) {
const hit = cache[str];
return hit || (cache[str] = fn(str));
};
}
// 将连字符分隔的字符串驼峰化
const camelizeRE = /-(\w)/g;
const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ""));
});
// 首字母大写
const capitalize = cached((str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
});
// 将驼峰字符串转化为中划线连接
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = cached((str) => {
return str.replace(hyphenateRE, "-$1").toLowerCase();
});
// 将类数组的对象转换为真正的数组
function toArray(list, start) {
start = start || 0;
let i = list.length - start;
const ret = new Array(i);
while (i--) {
ret[i] = list[i + start];
}
return ret;
}
// 将一个对象合并到目标对象中
// to:目标对象,_from待合并对象
function extend(to, _from) {
for (const key in _from) {
to[key] = _from[key];
}
return to;
}
// 将数组对象转换为对象
function toObject(arr) {
const res = {};
for (let i = 0; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i]);
}
}
return res;
}
// 判断两个数据是否相等(复杂类型不考虑引用地址)
function looseEqual(a, b) {
if (a === b) return true;
const isObjectA = isObject(a);
const isObjectB = isObject(b);
if (isObjectA && isObjectB) {
try {
const isArrayA = Array.isArray(a);
const isArrayB = Array.isArray(b);
if (isArrayA && isArrayB) {
return (
a.length === b.length &&
a.every((e, i) => {
return looseEqual(e, b[i]);
})
);
} else if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime();
} else if (!isArrayA && !isArrayB) {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
return (
keysA.length === keysB.length &&
keysA.every((key) => {
return looseEqual(a[key], b[key]);
})
);
} else {
/* istanbul ignore next */
return false;
}
} catch (e) {
/* istanbul ignore next */
return false;
}
} else if (!isObjectA && !isObjectB) {
return String(a) === String(b);
} else {
return false;
}
}
// 返回数组中可以找到一个值相等的第一个索引
// (如果value是普通对象,则数组必须包含相同形状的对象),如果不存在,则返回-1。
function looseIndexOf(arr, val) {
for (let i = 0; i < arr.length; i++) {
if (looseEqual(arr[i], val)) return i;
}
return -1;
}
// 确保一个函数只被调用一次。
function once(fn) {
let called = false;
return function () {
if (!called) {
called = true;
fn.apply(this, arguments);
}
};
}
版权声明:本文为weixin_44178305原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。