UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

247 lines (207 loc) 6.36 kB
'use strict'; exports.__esModule = true; var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); exports.typeOf = typeOf; exports.isArrayLike = isArrayLike; exports.isPromise = isPromise; exports.isPlainObject = isPlainObject; exports.shallowEqual = shallowEqual; exports.each = each; exports.pickOthers = pickOthers; exports.pickAttrsWith = pickAttrsWith; exports.isNil = isNil; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * 获取对象的类型 * @param {*} obj * @return {String} * * @example * typeOf([]) === 'Array' * typeOf() === 'Undefined' * typeOf(1) === 'Number' */ function typeOf(obj) { return Object.prototype.toString.call(obj).replace(/\[object\s|]/g, ''); } /** * 判断是否是数组或类数组对象 * @param {*} obj * @return {Boolean} * * @example * isArrayLike([]) === true * isArrayLike(arguments) === true * isArrayLike(this.props.children) === true */ function isArrayLike(obj) { var length = !!obj && 'length' in obj && obj.length; var type = typeOf(obj); return type === 'Array' || length === 0 || typeof length === 'number' && length > 0 && length - 1 in obj; } /** * 判断对象是否是一个promise,即是否可以用.then * @param {*} obj * @return {Boolean} */ function isPromise(obj) { return !!obj && ((typeof obj === 'undefined' ? 'undefined' : (0, _typeof3.default)(obj)) === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; } /** * 是否是一个纯净的对象 * @param {*} obj * @return {Boolean} * @reference https://github.com/jonschlinkert/is-plain-object */ function isPlainObject(obj) { if (typeOf(obj) !== 'Object') { return false; } var ctor = obj.constructor; if (typeof ctor !== 'function') { return false; } var prot = ctor.prototype; if (typeOf(prot) !== 'Object') { return false; } if (!prot.hasOwnProperty('isPrototypeOf')) { return false; } return true; } /** * 对象浅比较 * @param {Object} objA * @param {Object} objB * @param {Function} [compare] 手动调用方法比较 * @return {Boolean} 对象浅比较是否相等 * * @example * object.shallowEqual({a: 100}, {a: 100}); // true */ function shallowEqual(objA, objB, compare) { if (objA === objB) { return true; } // 其中一个不是object,则不相等 if (!objA || !objB || (typeof objA === 'undefined' ? 'undefined' : (0, _typeof3.default)(objA)) + (typeof objB === 'undefined' ? 'undefined' : (0, _typeof3.default)(objB)) !== 'objectobject') { return false; } var keyA = Object.keys(objA); var keyB = Object.keys(objB); var len = keyA.length; // key 数量不一致则不相等 if (len !== keyB.length) { return false; } var hasCallback = typeof compare === 'function'; for (var i = 0; i < len; i++) { var key = keyA[i]; if (!Object.prototype.hasOwnProperty.call(objB, key)) { return false; } var valA = objA[key]; var valB = objB[key]; var ret = hasCallback ? compare(valA, valB, key) : void 0; if (ret === false || ret === void 0 && valA !== valB) { return false; } } return true; } /** * 遍历对象或数组,或者类数组,例如React中的children对象、arguments等 * @param {Object|Array} obj * @param {Function} callback fn(n, i) or fn(val, key) * @param {Number} [direction = 1] 是否倒序遍历,只对数组有效 * @return {Object|Array} * * @example * // 遍历数组 * object.each([100, 200, 300], (n, i) => console.log(n, i)); * // 遍历json对象 * object.each({a: 100, b: 200}, (value, key) => console.log(key, value)); * // 遍历React子节点 * object.each(this.props.children, (child, index) => console.log(child)); * // 遍历arguments * object.each(arguments, (arg, i) => console.log(arg)); */ function each(obj, callback, direction) { var reversed = direction === -1; var length = obj.length; var value = void 0, i = reversed ? length - 1 : 0; if (isArrayLike(obj)) { for (; i < length && i >= 0; reversed ? i-- : i++) { value = callback.call(obj[i], obj[i], i); if (value === false) { break; } } } else { for (i in obj) { /* istanbul ignore else */ if (obj.hasOwnProperty(i)) { value = callback.call(obj[i], obj[i], i); if (value === false) { break; } } } } return obj; } // @private 判断key是否在数组或对象中 var _isInObj = function _isInObj(key, obj, isArray) { return isArray ? obj.indexOf(key) > -1 : key in obj; }; /** * 过滤出其它属性 * @param {Object|Array} holdProps 过滤的参照对象,最终的结果只保留不在参照对象中的key * @param {Object} props 被过滤的对象 * @return {Object} others * * @example * object.pickOthers(FooComponent.propTypes, this.props); * object.pickOthers(['className', 'onChange'], this.props); */ function pickOthers(holdProps, props) { var others = {}; var isArray = typeOf(holdProps) === 'Array'; for (var key in props) { if (!_isInObj(key, holdProps, isArray)) { others[key] = props[key]; } } return others; } /** * 过滤出带prefix的属性 * @param {Object} holdProps 过滤的参照对象,最终的结果只保留不在参照对象中的key * @param {string} prefix 包含的字符串 * @return {Object} others * * @example * object.pickAttrsWith(FooComponent.propTypes, 'data-'); */ function pickAttrsWith(holdProps, prefix) { var others = {}; for (var key in holdProps) { if (key.match(prefix)) { others[key] = holdProps[key]; } } return others; } /** * Checks if value is `null` or `undefined`. * @param {*} value * @return {Boolean} */ function isNil(value) { // It will returns `true` only if `null` or `undefined` compare with `null` // with loose equaliy return value == null; // eslint-disable-line eqeqeq }