UNPKG

jcommon

Version:

JavaScript 常用纯函数工具库

1,603 lines (1,591 loc) 102 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jcommon = {})); })(this, (function (exports) { 'use strict'; function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var n = 0, F = function () {}; return { s: F, n: function () { return n >= r.length ? { done: !0 } : { done: !1, value: r[n++] }; }, e: function (r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function () { t = t.call(r); }, n: function () { var r = t.next(); return a = r.done, r; }, e: function (r) { u = !0, o = r; }, f: function () { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _regeneratorRuntime() { _regeneratorRuntime = function () { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function (t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function (t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(typeof e + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function (e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function () { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function (e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function (t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function (t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function (e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } /** * @category Array * @description: 处理复杂数组的两级排序(一级按照自定义顺序,二级可正序倒序) * @author: wuxh * @Date: 2020-05-06 11:37:17 * @param {arr} 需要处理的数组 * @param {options} 额外参数 * @return: {Array} 排序后的数组 * ``` * doubleRanking( * [ * {education: '本科', age: 26}, * {education: '小学', age: 25}, * {education: '本科', age: 24}, * {education: '小学', age: 23} * ], * { * filterRuleKey: 'education', * rule: ['小学', '本科'], * sortKey: 'age', * sortOrder: 1 * } * ) * => [ * {education: '小学', age: 24}, * {education: '小学', age: 26} * {education: '本科', age: 23}, * {education: '本科', age: 25}, * ] * ``` */ var doubleRanking = function doubleRanking(arr, options) { var defOptions = { filterRuleKey: '', rule: [], sortKey: '', sortOrder: 1 // 二级排序规则 }; var _defOptions$options = _objectSpread2(_objectSpread2({}, defOptions), options), _defOptions$options$s = _defOptions$options.sortKey, sortKey = _defOptions$options$s === void 0 ? '' : _defOptions$options$s, _defOptions$options$f = _defOptions$options.filterRuleKey, filterRuleKey = _defOptions$options$f === void 0 ? '' : _defOptions$options$f, _defOptions$options$r = _defOptions$options.rule, rule = _defOptions$options$r === void 0 ? [] : _defOptions$options$r, _defOptions$options$s2 = _defOptions$options.sortOrder, sortOrder = _defOptions$options$s2 === void 0 ? 1 : _defOptions$options$s2; if (rule.length === 0) { return arr; } arr = arr.filter(function (d) { return !rule || rule.indexOf(d[filterRuleKey]) !== -1; }); var temp = {}; var _iterator = _createForOfIteratorHelper(arr), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var element = _step.value; if (Object.prototype.hasOwnProperty.call(temp, element[filterRuleKey])) { temp[element[filterRuleKey]].push(element); } else { temp[element[filterRuleKey]] = [element]; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } for (var k in temp) { temp[k] = temp[k].sort(function (a, b) { return a[sortKey] > b[sortKey] ? 1 * sortOrder : -1 * sortOrder; }); } var result = []; for (var i = 0; i < rule.length; i++) { if (Object.prototype.hasOwnProperty.call(temp, rule[i])) { result = result.concat(temp[rule[i]]); } } return result; }; /** * @category Array * @description: 产生随机数据 * @author: wxingheng * @Date: 2022-10-12 11:08:50 * @param {number} num 数量 * @param {Array} arr 每个元素对象的keys * @return {*} ``` randomData(2, ['name', 'value']) => [{"name":"name323","value":"value699"},{"name":"name573","value":"value393"}] ``` */ var randomData = function randomData(num, arr) { var result = []; for (var i = 0; i < num; i++) { var obj = {}; for (var j = 0; j < arr.length; j++) { obj[arr[j]] = arr[j] + String(Math.random()).substr(15); } result.push(obj); } return result; }; /** * @category Array * @description: 数值转对象 (常用于处理后台返回的枚举转换,工作中很常用) * @author: wuxh * @Date: 2020-05-06 11:51:49 * @param {object} arr 需要作为转换后对象的key需要转换的数组 * @param {string} key 需要作为转换后对象的key * @param {*} v 对象的value取值,默认是数组的每一个元素作为值 * @return: Object ``` const arr = arr = [{name: 111, value: 222},{name: 333, value:444}] arrByObj(arr, 'name') => {"111":{"name":111,"value":222},"333":{"name":333,"value":444}} arrByObj(arr, 'name', value) => {"111":222,"333":444} ``` */ var arrByObj = function arrByObj(arr, key) { var v = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; if (Object.prototype.toString.call(arr) !== '[object Array]') { console.error('arrByObj 参数错误,请检查:', arr); return {}; } var obj = {}; arr.forEach(function (d) { obj[d[key]] = v ? d[v] : d; }); return obj; }; /** * @category Array * @description: 简单数组去重,Set 处理 * @author: wxingheng * @Date: 2022-10-12 11:16:32 * @param {string} arr * @return {*} ``` uniqueArray([1,1,1,1,1]) => [1]; uniqueArray([1,2,3,4,5]) => [1,2,3,4,5]; ``` */ var uniqueArray = function uniqueArray(arr) { if (!Array.isArray(arr)) { throw new Error('The first parameter must be an array'); } if (arr.length == 1) { return arr; } return _toConsumableArray(new Set(arr)); }; /** * @category Array * @description: 数组交集 * @author: wxingheng * @Date: 2022-05-18 10:56:47 * @param {Iterable} a * @param {Iterable} b * @return {*} Array * ``` * difference([2,3,4,5], [1,2,3,4]) => [5, 1] ; * difference([1,2,3,4], [2,3,4,5]) => [1, 5]; * difference([1,2,3,4], [1,2,3,4]) => []; * difference([1,2,3,4], []) => [1, 2, 3, 4] * ``` */ var difference = function difference(a, b) { var set1 = new Set(a), set2 = new Set(b); return [].concat(_toConsumableArray(new Set(_toConsumableArray(set1).filter(function (x) { return !set2.has(x); }))), _toConsumableArray(new Set(_toConsumableArray(set2).filter(function (x) { return !set1.has(x); })))); }; /** * @category Array * @description: 数组元素是否相同 * @author: wxingheng * @Date: 2022-05-18 10:56:04 * @param {any} arr1 * @param {any} arr2 * @return {*} ``` arrayCompare([2,3,4,5], [5,4,3,2]) => true ; arrayCompare([2,3,4,5], [5,4,3,2,1]) => false; arrayCompare([2,3,4,5], []) => true; arrayCompare([], [1,2,3,4]) => false; arrayCompare([1,2,3,4], []) => true; ``` */ var arrayCompare = function arrayCompare(arr1, arr2) { return arr1.length === arr2.length && arr1.every(function (a) { return arr2.some(function (b) { return a === b; }); }) && arr2.every(function (_b) { return arr1.some(function (_a) { return _a === _b; }); }); }; /** * @category Array * @description: 数组排序的回调函数,用于sort方法,按照对象的某个属性进行中文排序 * @author: wxingheng * @Date: 2022-09-30 11:43:11 * @param {string} key 排序的属性 * @return {*} * ``` * arr.sort(sortCallBackChinese('name')) => [{name: '张三'}, {name: '李四'}] * ``` */ var sortCallBackChinese = function sortCallBackChinese(key) { return function (a, b) { return a[key].localeCompare(b[key], 'zh'); }; }; /** * @category Array * @description: * @author: wxingheng * @Date: 2022-09-30 11:45:04 * @param {string} key 对象的key * @param {boolean} desc 是否倒序, 默认是正序 * @return {*} * ``` * arr.sort(sortCallBackNumber('age')) => [{age: 18}, {age: 20}] * arr.sort(sortCallBackNumber('age', true)) => [{age: 20}, {age: 18}] * ``` */ var sortCallBackTime = function sortCallBackTime(key) { var desc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; return function (a, b) { var ratio = desc ? 1 : -1; return new Date(convertDateToStandard(b[key])).getTime() - new Date(convertDateToStandard(a[key])).getTime() > 0 ? 1 * ratio : -1 * ratio; }; }; /** * @category Array * @description: reduce方法,用于数组对象的求和 * @author: wxingheng * @Date: 2022-09-30 11:51:39 * @param {string} key * @return {*} * ``` * arr.reduce(reduceSum('num'), 0) => 10 * ``` */ var reduceCallBackNumber = function reduceCallBackNumber(key) { return function (acc, cur) { var value = cur[key] || 0; if (typeof value === 'string') { value = isNaN(Number(value)) ? 0 : Number(value); } return acc + value; }; }; /* * @Author: wuxh * @Date: 2020-05-04 21:14:00 * @LastEditTime: 2023-05-19 23:25:47 * @LastEditors: wxingheng * @Description: 浏览器相关 * @FilePath: /jcommon/src/browser/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 获取浏览器相关信息 * @author: wuxh * @Date: 2020-05-06 11:53:35 * @param {} * @return: Object * @example: ``` getBrowserInfo() => {name: "Chrome", version: "81.0.4044.129"} ``` */ var getBrowserInfo = function getBrowserInfo() { var e, t, r; var o = { name: 'other', version: '0' }, i = navigator.userAgent.toLowerCase(); for (t = [['WeiXin', /micromessenger\/([^\s]+)/], ['QQ', /qq\/([^\s]+)/], ['QQBrowser', /(?:qqbrowser|qqlivebrowser)\/([^\s]+)/], ['JDAPP', /jdapp;/], ['QIHU', /qihu|360se/], ['LieBao', /(?:lbbrowser|liebaofast)\/?([\d\.]+)?/], ['Sogou', /(?:metasr|sogou[\w]*)[ \/]([\d\.]+)/], ['Opera', /(?:opera|opr|oupeng)\/([\d\.]+)/], ['BaiduBrowser', /(?:bidubrowser|baidubrowser)[\/ ]?([\d\.\w]+)/], ['BaiduBox', /baiduboxapp|baiduboxpad/], ['UC', /(?:ucweb|ucbrowser)\/?([\d\.]+)/], ['Maxthon', /maxthon\/([\d\.]+)/], ['Samsung', /samsungbrowser\/([\d\.]+)/], ['Dolphin', /aphone|apad/], ['2345', /2345/], ['Miui', /miuibrowser\/([\d\.]+)/], ['OppoBrowser', /oppobrowser\/([\d\.]+)/], ['MeiZu', /mz-/], ['Weibo', /weibo/], ['Youku', /youku/], ['NewsApp', /newsapp/], ['AliApp', /aliapp/], ['Firefox', /firefox\/([\d\.\w]+)/], ['Chrome', /chrome\/([\d\.]+)/], ['IE', /msie[ ](\d+\.\d+)/], ['Safari', /safari\/([\d\.]+)/]], e = 0; e < t.length; e++) if (r = i.match(t[e][1])) { o.name = t[e][0], o.version = r[1] || '0'; break; } return o; }; /* * @Author: wuxh * @Date: 2020-05-04 21:17:39 * @LastEditTime: 2021-09-07 16:45:27 * @LastEditors: wuxh * @Description: 数据持久化,缓存 * @FilePath: /jcommon/src/cache/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 删除 * @author: wuxh * @Date: 2020-05-06 11:56:29 * @param {key} * @return: undefined * @example: removeStorage('test') => undefined */ var removeStorage = function removeStorage(key) { window.localStorage.removeItem(key); }; /** * @description: 保存 * @author: wuxh * @Date: 2020-05-06 11:56:29 * @param {key} * @param {value} * @param {isJson} * @return: undefined * @example: saveStorage('test', '001') => undefined */ var saveStorage = function saveStorage(key, value) { if (typeof value === 'undefined' || typeof value === 'function') { window.localStorage.setItem(key, ''); } else { try { window.localStorage.setItem(key, JSON.stringify(value)); } catch (e) { console.error(e); } } }; /** * @description: 获取 * @author: wuxh * @Date: 2020-05-06 12:00:37 * @param {key} * @return: String * @example: getStorage('test') => '001' */ var getStorage = function getStorage(key) { var value = window.localStorage.getItem(key) || ''; if (typeof value === 'undefined' || typeof value === 'function') { return ''; } else { return JSON.parse(value); } }; /** * @description: 是否支持local * @author: wuxh * @Date: 2020-05-06 12:01:43 * @param * @return: Boolean * @example: isSupportStorage() => true */ var isSupportStorage = function isSupportStorage() { if (!window.localStorage) { return false; } try { window.localStorage.setItem('JUTILS_STOARGE_TEST', 'true'); window.localStorage.removeItem('JUTILS_STOARGE_TEST'); return true; } catch (e) { return false; } }; /* * @Author: wuxh * @Date: 2020-06-09 09:27:33 * @LastEditTime: 2023-05-24 15:07:09 * @LastEditors: wxingheng * @Description: * @FilePath: /jcommon/src/cookie/index.ts */ /** * @description: 获取cookie值 * @author: wuxh * @Date: 2020-06-09 09:28:06 * @param {type} * @return: string * @example: getCookie('name') => 123 */ var getCookie = function getCookie(name) { var arr = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)(;|$)')); if (arr != null) return unescape(arr[2]); return null; }; /* * @Author: wuxh * @Date: 2020-05-04 21:24:53 * @LastEditTime: 2023-05-19 23:28:35 * @LastEditors: wxingheng * @Description: 时间相关 * @FilePath: /jcommon/src/date/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 获取两个时间的间隔 * @author: wuxh * @Date: 2020-05-06 12:04:39 * @param {st} * @param {et} * @return: String * @example: dateInterval(new Date().getTime(), 1589661011714) => 11天13小时46分钟21秒 */ var dateInterval = function dateInterval(st, et) { var timeLeft = [0, 0, 0, 0]; var timeStr = ''; var ts = et > st ? parseInt(((et - st) / 1000).toString()) : 0; timeLeft[0] = ts > 86400 ? parseInt((ts / 86400).toString()) : 0; ts = ts - timeLeft[0] * 86400; timeLeft[1] = ts > 3600 ? parseInt((ts / 3600).toString()) : 0; ts = ts - timeLeft[1] * 3600; timeLeft[2] = ts > 60 ? parseInt((ts / 60).toString()) : 0; timeLeft[3] = ts - timeLeft[2] * 60; timeStr = timeLeft[0] > 0 ? timeLeft[0] + '天' : ''; timeStr += timeLeft[0] <= 0 && timeLeft[1] <= 0 ? '' : timeLeft[1] + '小时'; timeStr += timeLeft[0] <= 0 && timeLeft[1] <= 0 && timeLeft[2] <= 0 ? '' : timeLeft[2] + '分钟'; timeStr += timeLeft[0] <= 0 && timeLeft[1] <= 0 && timeLeft[2] <= 0 && timeLeft[3] <= 0 ? '' : timeLeft[3] + '秒'; return timeStr; }; /** * @description: 字符串补0,目前提供给dateFormat使用 * @author: wuxh * @Date: 2020-05-11 14:01:20 * @param {v} 需要处理的数据 String | Number * @param {size} 期望得到的总位数 * @return: String * @example: addZero(12, 1) => 12 addZero(12, 2) => 12 addZero(12, 3) => 012 */ var addZero = function addZero(v, size) { return v.toString().padStart(size, '0'); }; /** * @description: 时间的转换(目前支持 年,月,日,时,分,秒,星期) * @author: wuxh * @Date: 2020-05-06 12:05:28 * @param {date} * @param {formatStr} * @return: String * @example: dateFormat(new Date(), '当前时间 YY-MM-DD HH:II:SS 星期W') => "当前时间 20-05-11 14:07:02 星期一" */ var dateFormat = function dateFormat(date, formatStr) { var arrWeek = ['日', '一', '二', '三', '四', '五', '六'], str = formatStr.replace(/yyyy|YYYY/, date.getFullYear().toString()).replace(/yy|YY/, addZero(date.getFullYear() % 100, 2)).replace(/mm|MM/, addZero(date.getMonth() + 1, 2)).replace(/m|M/g, (date.getMonth() + 1).toString()).replace(/dd|DD/, addZero(date.getDate(), 2)).replace(/d|D/g, date.getDate().toString()).replace(/hh|HH/, addZero(date.getHours(), 2)).replace(/h|H/g, date.getHours().toString()).replace(/ii|II/, addZero(date.getMinutes(), 2)).replace(/i|I/g, date.getMinutes().toString()).replace(/ss|SS/, addZero(date.getSeconds(), 2)).replace(/s|S/g, date.getSeconds().toString()).replace(/w/g, date.getDay().toString()).replace(/W/g, arrWeek[date.getDay()]); return str; }; /** * @description: 时间的转换(目前支持 年,月,日,时,分,秒,星期), 与dateFormat的区别是,这个方法可以传入时间戳 * @author: wxingheng * @Date: 2022-09-30 11:46:22 * @return {date} * @example: convertDateToView(new Date(), '当前时间 YY-MM-DD HH:II:SS 星期W') */ var convertDateToView = function convertDateToView(date) { var template = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "YYYY-MM-DD HH:II:SS"; var defaultResult = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; if (!date) return defaultResult; try { if (typeof date === "string") { date = isNaN(Number(date)) ? new Date(date) : Number(date); } if (typeof date === "number") { date = new Date(date); } if (date instanceof Date) { return dateFormat(date, template); } return ""; } catch (error) { return ""; } }; /** * @description: 时间的转换 "YYYY-MM-DD HH:II:SS" * @author: wxingheng * @Date: 2022-09-30 11:48:15 * @param {string} date * @return {*} * @example: convertDateToStandard(new Date()) => "2021-09-30 11:48:15" */ var convertDateToStandard = function convertDateToStandard(date) { return convertDateToView(date); }; /** * @description: 时间的转换 "YYYY-MM-DD" * @author: wxingheng * @Date: 2022-09-30 11:49:14 * @param {string} date * @return {*} * @example: convertDateToStandardDay(new Date()) => "2021-09-30" */ var convertDateToStandardDay = function convertDateToStandardDay(date) { return convertDateToView(date, "YYYY-MM-DD"); }; /** * @description: 时间的转换 "YYYY-MM-DD HH" * @author: wxingheng * @Date: 2022-09-30 11:49:37 * @param {string} date * @return {*} * @example: convertDateToStandardHours(new Date()) => "2021-09-30 11" */ var convertDateToStandardHours = function convertDateToStandardHours(date) { return convertDateToView(date, "YYYY-MM-DD HH"); }; /** * @description: 获取当前月份的天数 * @author: wuxh * @Date: 2020-05-06 12:06:24 * @param {str} * @return: Number * @example: dateMonthDays('2020-05-06') => 31 */ var dateMonthDays = function dateMonthDays(str) { var curDate = str ? new Date(str) : new Date(); var curMonth = curDate.getMonth(); curDate.setMonth(curMonth + 1); curDate.setDate(0); return curDate.getDate(); }; /** * @description: 时间个性化输出功能 * @author: wuxh * @Date: 2020-06-09 09:44:23 * @param {type} * @return: string * @example: 1、< 60s, 显示为“刚刚” 2、>= 1min && < 60 min, 显示与当前时间差“XX分钟前” 3、>= 60min && < 1day, 显示与当前时间差“今天 XX:XX” 4、>= 1day && < 1year, 显示日期“XX月XX日 XX:XX” 5、>= 1year, 显示具体日期“XXXX年XX月XX日 XX:XX” timeFormat(new Date()) => '刚刚' */ var timeFormat = function timeFormat(time) { var date = new Date(time), curDate = new Date(), year = date.getFullYear(), month = date.getMonth() + 10, day = date.getDate(), hour = date.getHours(), minute = date.getMinutes(), curYear = curDate.getFullYear(), curHour = curDate.getHours(); var timeStr; if (year < curYear) { timeStr = year + '年' + month + '月' + day + '日 ' + hour + ':' + minute; } else { var pastTime = curDate.getTime() - date.getTime(), pastH = pastTime / 3600000; if (pastH > curHour) { timeStr = month + '月' + day + '日 ' + hour + ':' + minute; } else if (pastH >= 1) { timeStr = '今天 ' + hour + ':' + minute + '分'; } else { var pastM = curDate.getMinutes() - minute; if (pastM > 1) { timeStr = pastM + '分钟前'; } else { timeStr = '刚刚'; } } } return timeStr; }; /** * @description: 获取当前月份天数 * @author: wuxh * @Date: 2021-08-21 22:43:58 * @param {*} str YYYY-MM-DD mm:ss * @return {*} number * @example: */ var getCountDays = function getCountDays(str) { var curDate = new Date(str); var curMonth = curDate.getMonth(); curDate.setMonth(curMonth + 1); curDate.setDate(0); return curDate.getDate(); }; /* * @Author: wuxh * @Date: 2020-05-05 14:49:34 * @LastEditTime: 2023-05-19 23:49:17 * @LastEditors: wxingheng * @Description: 用户设备相关(客户端系统) * @FilePath: /jcommon/src/devices/index.ts * @https://github.com/wxingheng/jcommon */ var osInfo = function osInfo(e) { e = e || navigator.userAgent; var t = { os: 'other', version: '' }, r = [['android', /Android;?[\s\/]+([\d.]+)?/], ['android', /jdapp;android;[\d.]+;([\d.]+);/], ['android', /[aA]ndroid;/], ['ipad', /iPad;.*?OS\s([\d_]+)/], ['ipod', /iPod(?:\stouch)?;.*?\sOS\s([\d_]+)?/], ['iphone', /CPU\siPhone\s(?:OS\s)?([\d_]+)/], ['windows', /Windows NT/], ['mac', /Macintosh;.*?Mac OS X\s([\d._]+)/], ['windows phone', /Windows Phone\s([\d.]+)?/], ['symbianos', /SymbianOS\/([\d.]+)?/], ['bb', /BlackBerry|BB10|RIM Tablet OS\s([\d.]+)?/], ['linux', /linux/i]]; var o = 0; for (; o < r.length; o++) { var i = r[o], a = e.match(i[1]); if (a) { t.os = i[0], t.version = (a[1] || '').replace(/_/g, '.'); break; } } return t; }; /* * @Author: wuxh * @Date: 2020-05-06 10:16:25 * @LastEditTime: 2023-05-24 15:11:02 * @LastEditors: wxingheng * @Description: 数处理相 * @FilePath: /jcommon/src/math/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 范围随机整数 * @author: wuxh * @Date: 2020-05-06 12:09:34 * @param {str} * @param {end} * @return: Number * @example: scopeRandom(1, 10) => 3 */ var scopeRandom = function scopeRandom(str, end) { return Math.floor(Math.random() * (end - str) + str); }; /** * @description: 保留到小数点以后n位 * @author: wuxh * @Date: 2021-09-02 22:54:36 * @param {number} number * @param {*} no * @return {*} Number * @example: cutNumber('3123.22312') => 3123.22 */ var cutNumber = function cutNumber(number) { var no = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; if (typeof number != 'number') { number = Number(number); } return Number(number.toFixed(no)); }; /* * @Author: wuxh * @Date: 2020-05-05 14:52:11 * @LastEditTime: 2023-05-24 15:12:14 * @LastEditors: wxingheng * @Description: 移动端相关 * @FilePath: /jcommon/src/mobile/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 是否是QQ平台 * @author: wuxh * @Date: 2020-05-06 12:10:41 * @param * @return: Boolean * @example: isQQ() => false */ var isQQ = function isQQ() { if (/qq\/([\d\.]+)*/i.test(navigator.userAgent)) { return true; } return false; }; /** * @description: 是否是微信平台 * @author: wuxh * @Date: 2020-05-06 12:10:41 * @param * @return: Boolean * @example: isWX() => false */ var isWX = function isWX() { if (/MicroMessenger/i.test(navigator.userAgent)) { return true; } return false; }; /** * @description: 获取手机运营商 * @author: wuxh * @Date: 2020-05-06 12:11:39 * @param {} * @return: '移动' | '电信' | '联通' | '未知' * @example: operattelecom('13419595634') => 移动 */ var operattelecom = function operattelecom(e) { var i = '134,135,136,137,138,139,150,151,152,157,158,159,187,188,147,182,183,184,178', n = '130,131,132,155,156,185,186,145,176', a = '133,153,180,181,189,177,173,170', o = e || '', r = o.substring(0, 3), d = o.substring(0, 4), s = !!/^1\d{10}$/.test(o) && (n.indexOf(r) >= 0 ? '联通' : a.indexOf(r) >= 0 ? '电信' : '1349' == d ? '电信' : i.indexOf(r) >= 0 ? '移动' : '未知'); return s; }; /** * @description: 是否是安卓设备 * @author: wuxh * @Date: 2020-06-09 09:31:04 * @param {type} * @return: boolean * @example: isAndroidMobileDevice() => false */ var isAndroidMobileDevice = function isAndroidMobileDevice() { return /android/i.test(navigator.userAgent.toLowerCase()); }; /** * @description: 是否是苹果设备 * @author: wuxh * @Date: 2020-06-09 09:31:55 * @param {type} * @return: boolean * @example: isAppleMobileDevice() => true */ var isAppleMobileDevice = function isAppleMobileDevice() { return /iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()); }; /* * @Author: wuxh * @Date: 2020-05-05 15:08:11 * @LastEditTime: 2023-05-19 22:57:22 * @LastEditors: wxingheng * @Description: 校验相关 * @FilePath: /jcommon/src/validate/index.ts * @https://github.com/wxingheng/jcommon */ /** * @description: 身份证号码校验(精准) * @author: wuxh * @Date: 2020-05-06 13:49:58 * @param {e} * @return: String<msg> | Boolean * @example: isUserId('421182199409274710') => '' isUserId('421182199409') => '身份证号码长度应该为18位' */ var isUserId = function isUserId(e) { var i, t, a, n, s, o, r, d, l, c; var p = { 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海', 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北', 43: '湖南', 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外' }; if (s = ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'], o = ['7', '9', '10', '5', '8', '4', '2', '1', '6', '3', '7', '9', '10', '5', '8', '4', '2'], i = '', !e) return '身份证号码不能为空'; if (18 != e.length) return '身份证号码长度应该为18位'; if (18 == e.length ? i = e.substring(0, 17) : 15 == e.length && (i = e.substring(0, 6) + '19' + e.substring(6, 15)), !/^\d+$/.test(i)) return '身份证格式错误'; if (t = i.substring(6, 10), a = i.substring(10, 12), n = i.substring(12, 14), false === /[1-9]\d{3}-(0[1-9]|1[0-2])-([0-2]\d|3[0-1])/.test(t + '-' + a + '-' + n)) return '身份证生日无效。'; if (new Date().getFullYear() - Number(t) > 150 || new Date().getTime() - new Date(Number(t), Number(a) - 1, Number(n)).getTime() < 0) return '身份证生日不在有效范围'; if (Number(a) > 12 || 0 === Number(a)) return '身份证月份无效'; if (Number(n) > 31 || 0 == Number(n)) return '身份证日期无效'; if (!p[i.substring(0, 2)]) return '身份证地区编码错误'; for (d = 0, r = 0; r < 17; r++) d += Number(i.charAt(r)) * Number(o[r]); return l = d % 11, c = s[l], i += c, 18 != e.length ? '' : i != e.toLowerCase() ? '不是合法的身份证号码' : ''; }; /** * @description: 精准判断数据类型 * @author: wuxh * @Date: 2020-05-06 13:51:50 * @param {data} any * @param {type} type 'String' | 'Number' | 'Boolean' | 'Undefined' | 'Null' | 'Function' | 'Date' | 'Array' | 'RegExp' | 'Error' | 'Object' * @return: Boolean * @example: isType(123, 'String') => false isType('123', 'String') => true */ var isType = function isType(data, type) { return Object.prototype.toString.call(data) === "[object ".concat(type, "]"); }; /** * @description: 判断String类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isString(123) => false isString('') => true */ var isString = function isString(data) { return isType(data, 'String'); }; /** * @description: 判断Number类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isNumber(123) => true isNumber('') => false */ var isNumber = function isNumber(data) { return isType(data, 'Number'); }; /** * @description: 判断Boolean类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isBoolean(false) => true isBoolean('false') => false */ var isBoolean = function isBoolean(data) { return isType(data, 'Boolean'); }; /** * @description: 判断Undefined类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isUndefined(undefined) => true isUndefined('undefined') => false */ var isUndefined = function isUndefined(data) { return isType(data, 'Undefined'); }; /** * @description: 判断Null类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isNull(null) => true isNull('null') => false */ var isNull = function isNull(data) { return isType(data, 'Null'); }; /** * @description: 判断Function类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isFunc(() => 123) => true isFunc(123) => false */ var isFunc = function isFunc(data) { return isType(data, 'Function'); }; /** * @description: 判断Date类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isDate(() => new Date()) => false isDate(new Date()) => true */ var isDate = function isDate(data) { return isType(data, 'Date'); }; /** * @description: 判断Array类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isArray([]) => true isArray(![]) => false */ var isArray = function isArray(data) { return isType(data, 'Array'); }; /** * @description: 判断RegExp类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isReg(new RegExp()) => true isReg(![]) => false */ var isReg = function isReg(data) { return isType(data, 'RegExp'); }; /** * @description: 判断Error类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isError(new Error()) => true isError(![]) => false */ var isError = function isError(data) { return isType(data, 'Error'); }; /** * @description: 判断Object类型 * @author: wuxh * @Date: 2020-05-06 13:53:16 * @param {data} any * @return: Boolean * @example: isObject({}) => true isObject(![]) => false */ var isObject = function isObject(data) { return isType(data, 'Object'); }; /** * @description: 手机号校验 * @author: wuxh * @Date: 2020-06-09 09:21:15 * @param {type} * @return: boolean * @example: isPhone('13419595634') => true */ var isPhone = function isPhone(phone) { if (!phone) { return false; } var phoneReg = /(^1[3|4|5|7|8]\d{9}$)|(^09\d{8}$)/; return phoneReg.test(phone); }; /** * @description: 校验是否为邮箱地址 * @author: wuxh * @Date: 2020-06-09 09:49:29 * @param {type} * @return: boolean * @example: isEmail('wxingheng@outlook.com') => true */ var isEmail = function isEmail(str) { return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(str); }; /** * @description: 判断 js是否是false, 0除外。 * @author: wuxh * @Date: 2021-09-02 22:01:50 * @param {any} value * @return {*} value === 0 ? false : !value * @example: isFalsy('') => true isFalsy(0) => false isFalsy(null) => true isFalsy(undefined) => true */ var isFalsy = function isFalsy(value) { return value === 0 ? false : !value; }; /** * @description: 判断是否为空 undefined || null || "" * @author: wuxh * @Date: 2021-09-02 22:03:36 * @param {any} value * @return {*} boolean * @example: isVoid(0) => false isVoid(undefined) => true isVoid('') => true isVoid(null) => true isVoid() => true */ var isVoid = function isVoid(value) { return value === undefined || value === null || value === ''; }; /** * @description: 获取嵌套数据,处理空值异常 * @author: wuxh * @Date: 2020-05-06 12:13:59 * @param defaultResult 默认值 * @param args 属性访问路径 * @returns 目标值或默认值 * @example: getV('', {name: {children: 123}}, 'name', 'children') => 123 */ var getV = function getV(defaultResult) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (!args.length) return defaultResult; return args.reduce(function (a, b) { var _a$b; return (_a$b = a === null || a === void 0 ? void 0 : a[b]) !== null && _a$b !== void 0 ? _a$b : defaultResult; }); }; /** * @description: 深拷贝,克隆(只包含可遍历属性<常用>) * @author: wuxh * @Date: 2020-05-06 12:14:45 * @param {obj} * @return: Object * @example: clone({name: 123}) => {name: 123} */ var _cloneObj = function cloneObj(obj) { if (isNull(obj) || isUndefined(obj)) { return ''; } var str, newObj = obj.constructor === Array ? [] : {}; if (_typeof(obj) !== 'object') { return; } else if (JSON) { str = JSON.stringify(obj), newObj = JSON.parse(str); } else { for (var i in obj) { newObj[i] = _typeof(obj[i]) === 'object' ? _cloneObj(obj[i]) : obj[i]; } } return newObj; }; var cloneJson = function cloneJson(obj) { if (_typeof(obj) != 'object') { return obj; } if (obj == null) { return obj; } return JSON.parse(JSON.stringify(obj)); }; /** * @description: 深度合并对象(当前用于合并系统配置文件 app-data.json) 已存在的属性默认不覆盖 * @author: wuxh * @Date: 2020-05-06 12:15:30 * @param {oldObj} * @param {newObj} * @param {keys} 强制覆盖属性的key组成的数组 * @return: Object * @example: mergeObj({name: 111}, {name:333, value: 222}, []) => {name: 111, value: 222} mergeObj({name: 111}, {name:333, value: 222}, ['name']) => {name: 333, value: 222} */ var _mergeObj = function mergeObj(oldObj, newObj, keys) { for (var key in newObj) { if (isObject(newObj[key]) && isObject(oldObj[key])) { oldObj[key] = _mergeObj(oldObj[key], newObj[key], keys); } else if (Object.keys(oldObj).includes(key) && !keys.includes(key)) { continue; } else { oldObj[key] = newObj[key]; } } for (var _key2 in oldObj) { if (newObj[_key2] === undefined) { delet