Files
windyChenUtils/object.js
T
2026-05-27 14:28:02 +08:00

75 lines
2.3 KiB
JavaScript

/**
* 获取值的类型字符串
* @param {*} val - 任意值
* @returns {string} 类型名称,如 'String' 'Number' 'Array' 'Null' 'Undefined'
* @example
* Object.getTypeString('hello') // 'String'
* Object.getTypeString(123) // 'Number'
* Object.getTypeString(null) // 'Null'
*/
Object.getTypeString = function (val) {
return Object.prototype.toString.call(val).replace(/\[object |]/g, '');
};
/**
* 解析路径字符串为键数组
* @param {string} path - 路径字符串,支持点分隔、特殊键名、混合格式
* @returns {string[]} 键数组
* @private
*/
const _parsePath = (path) => {
const keys = [];
const keyRegex = /\[['"]([^'"]+)['"]\]|[^.\[\]]+/g;
let match;
while ((match = keyRegex.exec(path)) !== null) {
keys.push(match[1] || match[0]);
}
return keys;
};
/**
* 安全获取对象嵌套属性
* @param {string} path - 属性路径,支持多种格式:
* - 普通点分隔: 'a.b.c'
* - 特殊键名: "['key.with.dot']"
* - 混合: "['a.b'].c['d.e']"
* @param {*=} defaultValue - 路径不存在或值为 undefined 时返回的默认值
* @returns {*} 找到的属性值或默认值
* @example
* { a: { b: { c: 1 } } }.getPro('a.b.c') // 1
* { a: { b: { c: 1 } } }.getPro('a.x.y', 'default') // 'default'
* { 'x.y': { z: 2 } }.getPro("['x.y'].z") // 2
*/
Object.prototype.getPro = function (path, defaultValue) {
let result = this;
for (const key of _parsePath(path)) {
if (result == null) return defaultValue;
result = result[key];
}
return result !== undefined ? result : defaultValue;
};
/**
* 设置对象嵌套路径值(自动创建中间对象)
* @param {string} path - 属性路径,格式同 getPro
* @param {*} value - 要设置的值
* @returns {void}
* @example
* const obj = {};
* obj.setPro('a.b.c', 1); // obj => { a: { b: { c: 1 } } }
* obj.setPro("['x.y'].z", 2); // obj => { a: {...}, 'x.y': { z: 2 } }
*/
Object.prototype.setPro = function (path, value) {
const keys = _parsePath(path);
let target = this;
for (let i = 0; i < keys.length - 1; i++) {
if (target[keys[i]] == null || typeof target[keys[i]] !== 'object') {
target[keys[i]] = {};
}
target = target[keys[i]];
}
target[keys[keys.length - 1]] = value;
};