isObject
检查值是否为对象类型。
基础用法
typescript
import { isObject } from 'radash'
console.log(isObject({})) // true
console.log(isObject([])) // true
console.log(isObject(new Date())) // true
console.log(isObject(null)) // false
console.log(isObject(undefined)) // false
console.log(isObject('hello')) // false
console.log(isObject(123)) // false
语法
typescript
function isObject(value: any): value is object
参数
value
(any): 要检查的值
返回值
返回一个布尔值,如果值是对象则返回 true
,否则返回 false
。同时作为TypeScript类型守卫。
示例
基本类型检查
typescript
import { isObject } from 'radash'
// 对象类型
console.log(isObject({})) // true
console.log(isObject({ name: 'Alice' })) // true
console.log(isObject([])) // true
console.log(isObject([1, 2, 3])) // true
console.log(isObject(new Date())) // true
console.log(isObject(new RegExp('test'))) // true
console.log(isObject(new Map())) // true
console.log(isObject(new Set())) // true
// 非对象类型
console.log(isObject(null)) // false
console.log(isObject(undefined)) // false
console.log(isObject('hello')) // false
console.log(isObject(123)) // false
console.log(isObject(true)) // false
console.log(isObject(false)) // false
console.log(isObject(() => {})) // false
特殊对象检查
typescript
import { isObject } from 'radash'
// 内置对象
console.log(isObject(new Array())) // true
console.log(isObject(new Object())) // true
console.log(isObject(new String('hello'))) // true
console.log(isObject(new Number(123))) // true
console.log(isObject(new Boolean(true))) // true
// 函数对象
console.log(isObject(function() {})) // false
console.log(isObject(() => {})) // false
console.log(isObject(async () => {})) // false
// 原始值包装对象
console.log(isObject(new String('hello'))) // true
console.log(isObject(new Number(123))) // true
console.log(isObject(new Boolean(true))) // true
类型守卫使用
typescript
import { isObject } from 'radash'
function processValue(value: unknown) {
if (isObject(value)) {
// TypeScript 知道 value 是对象
console.log('Processing object:', Object.keys(value))
return Object.keys(value).length
}
console.log('Not an object')
return 0
}
console.log(processValue({ a: 1, b: 2 })) // Processing object: ['a', 'b'] 2
console.log(processValue([1, 2, 3])) // Processing object: ['0', '1', '2'] 3
console.log(processValue('hello')) // Not an object 0
数组过滤
typescript
import { isObject } from 'radash'
const mixedArray = [
{ name: 'Alice' },
[1, 2, 3],
'hello',
123,
new Date(),
null,
undefined,
() => {}
]
const objects = mixedArray.filter(isObject)
console.log(objects.length) // 3
const nonObjects = mixedArray.filter(item => !isObject(item))
console.log(nonObjects.length) // 5
对象属性检查
typescript
import { isObject } from 'radash'
const data = {
user: { name: 'Alice', age: 25 },
settings: { theme: 'dark', notifications: true },
items: [1, 2, 3],
count: 5,
name: 'test',
isActive: true
}
const objectProperties = Object.entries(data)
.filter(([key, value]) => isObject(value))
.map(([key, value]) => ({ key, type: Array.isArray(value) ? 'array' : 'object' }))
console.log(objectProperties)
// [
// { key: 'user', type: 'object' },
// { key: 'settings', type: 'object' },
// { key: 'items', type: 'array' }
// ]
深度对象检查
typescript
import { isObject } from 'radash'
function getObjectPaths(obj: any, path = ''): string[] {
const paths: string[] = []
if (!isObject(obj)) {
return paths
}
Object.keys(obj).forEach(key => {
const currentPath = path ? `${path}.${key}` : key
paths.push(currentPath)
if (isObject(obj[key])) {
paths.push(...getObjectPaths(obj[key], currentPath))
}
})
return paths
}
const nestedObject = {
user: {
profile: {
name: 'Alice',
settings: {
theme: 'dark'
}
}
},
data: [1, 2, 3]
}
console.log(getObjectPaths(nestedObject))
// ['user', 'user.profile', 'user.profile.name', 'user.profile.settings', 'user.profile.settings.theme', 'data']
API响应处理
typescript
import { isObject } from 'radash'
interface ApiResponse {
data: unknown
meta: unknown
errors: unknown
}
function processApiResponse(response: ApiResponse) {
const processed = {
data: isObject(response.data) ? response.data : {},
meta: isObject(response.meta) ? response.meta : {},
errors: isObject(response.errors) ? response.errors : {}
}
return processed
}
const response1: ApiResponse = {
data: { id: 1, name: 'Alice' },
meta: { total: 1, page: 1 },
errors: null
}
const response2: ApiResponse = {
data: 'not an object',
meta: 123,
errors: 'error string'
}
console.log(processApiResponse(response1))
// { data: { id: 1, name: 'Alice' }, meta: { total: 1, page: 1 }, errors: {} }
console.log(processApiResponse(response2))
// { data: {}, meta: {}, errors: {} }
配置验证
typescript
import { isObject } from 'radash'
interface Config {
server: unknown
database: unknown
api: unknown
}
function validateConfig(config: Config) {
const errors: string[] = []
if (!isObject(config.server)) {
errors.push('server must be an object')
}
if (!isObject(config.database)) {
errors.push('database must be an object')
}
if (!isObject(config.api)) {
errors.push('api must be an object')
}
return errors
}
const validConfig: Config = {
server: { port: 3000, host: 'localhost' },
database: { url: 'postgresql://localhost:5432/mydb' },
api: { version: 'v1', timeout: 5000 }
}
const invalidConfig: Config = {
server: 'localhost:3000',
database: null,
api: undefined
}
console.log(validateConfig(validConfig)) // []
console.log(validateConfig(invalidConfig)) // ['server must be an object', 'database must be an object', 'api must be an object']
表单数据处理
typescript
import { isObject } from 'radash'
interface FormData {
personalInfo: unknown
address: unknown
preferences: unknown
}
function validateFormData(data: FormData) {
const errors: string[] = []
if (!isObject(data.personalInfo)) {
errors.push('personalInfo must be an object')
}
if (!isObject(data.address)) {
errors.push('address must be an object')
}
if (!isObject(data.preferences)) {
errors.push('preferences must be an object')
}
return errors
}
const validFormData: FormData = {
personalInfo: { name: 'Alice', age: 25 },
address: { street: '123 Main St', city: 'Beijing' },
preferences: { theme: 'dark', notifications: true }
}
const invalidFormData: FormData = {
personalInfo: 'Alice',
address: null,
preferences: undefined
}
console.log(validateFormData(validFormData)) // []
console.log(validateFormData(invalidFormData)) // ['personalInfo must be an object', 'address must be an object', 'preferences must be an object']
数据库记录处理
typescript
import { isObject } from 'radash'
interface DatabaseRecord {
id: number
data: unknown
metadata: unknown
settings: unknown
}
function sanitizeDatabaseRecord(record: DatabaseRecord) {
return {
id: record.id,
data: isObject(record.data) ? record.data : {},
metadata: isObject(record.metadata) ? record.metadata : {},
settings: isObject(record.settings) ? record.settings : {}
}
}
const dbRecord: DatabaseRecord = {
id: 1,
data: { name: 'Product A', price: 29.99 },
metadata: { created: new Date(), updated: new Date() },
settings: null
}
console.log(sanitizeDatabaseRecord(dbRecord))
// { id: 1, data: { name: 'Product A', price: 29.99 }, metadata: { created: Date, updated: Date }, settings: {} }
事件对象处理
typescript
import { isObject } from 'radash'
interface EventData {
target: unknown
data: unknown
context: unknown
}
function processEvent(event: EventData) {
const processed = {
target: isObject(event.target) ? event.target : {},
data: isObject(event.data) ? event.data : {},
context: isObject(event.context) ? event.context : {}
}
return processed
}
const event: EventData = {
target: { id: 'button1', type: 'button' },
data: { x: 100, y: 200 },
context: null
}
console.log(processEvent(event))
// { target: { id: 'button1', type: 'button' }, data: { x: 100, y: 200 }, context: {} }
嵌套对象验证
typescript
import { isObject } from 'radash'
function validateNestedObject(obj: unknown, maxDepth = 5, currentDepth = 0): boolean {
if (currentDepth > maxDepth) {
return false
}
if (!isObject(obj)) {
return true
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (!validateNestedObject(obj[key], maxDepth, currentDepth + 1)) {
return false
}
}
}
return true
}
const validNestedObject = {
level1: {
level2: {
level3: {
value: 'deep'
}
}
}
}
const invalidNestedObject = {
level1: {
level2: {
level3: {
level4: {
level5: {
level6: {
value: 'too deep'
}
}
}
}
}
}
}
console.log(validateNestedObject(validNestedObject)) // true
console.log(validateNestedObject(invalidNestedObject)) // false
对象合并
typescript
import { isObject } from 'radash'
function deepMerge(target: any, source: any): any {
if (!isObject(target) || !isObject(source)) {
return source
}
const result = { ...target }
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (isObject(source[key]) && isObject(target[key])) {
result[key] = deepMerge(target[key], source[key])
} else {
result[key] = source[key]
}
}
}
return result
}
const obj1 = {
user: {
name: 'Alice',
settings: {
theme: 'dark'
}
},
data: [1, 2, 3]
}
const obj2 = {
user: {
age: 25,
settings: {
notifications: true
}
},
data: [4, 5, 6]
}
console.log(deepMerge(obj1, obj2))
// {
// user: {
// name: 'Alice',
// age: 25,
// settings: {
// theme: 'dark',
// notifications: true
// }
// },
// data: [4, 5, 6]
// }
对象比较
typescript
import { isObject } from 'radash'
function deepEqual(a: unknown, b: unknown): boolean {
if (a === b) {
return true
}
if (!isObject(a) || !isObject(b)) {
return false
}
const keysA = Object.keys(a)
const keysB = Object.keys(b)
if (keysA.length !== keysB.length) {
return false
}
for (const key of keysA) {
if (!keysB.includes(key)) {
return false
}
if (!deepEqual(a[key], b[key])) {
return false
}
}
return true
}
const obj1 = { a: 1, b: { c: 2, d: 3 } }
const obj2 = { a: 1, b: { c: 2, d: 3 } }
const obj3 = { a: 1, b: { c: 2, d: 4 } }
console.log(deepEqual(obj1, obj2)) // true
console.log(deepEqual(obj1, obj3)) // false
对象序列化
typescript
import { isObject } from 'radash'
function safeStringify(obj: unknown): string {
if (!isObject(obj)) {
return JSON.stringify(obj)
}
const seen = new WeakSet()
return JSON.stringify(obj, (key, value) => {
if (isObject(value)) {
if (seen.has(value)) {
return '[Circular Reference]'
}
seen.add(value)
}
return value
})
}
const circularObj: any = {
name: 'Alice',
data: { id: 1 }
}
circularObj.self = circularObj
console.log(safeStringify(circularObj))
// {"name":"Alice","data":{"id":1},"self":"[Circular Reference]"}
对象克隆
typescript
import { isObject } from 'radash'
function deepClone(obj: unknown): unknown {
if (!isObject(obj)) {
return obj
}
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item))
}
const cloned: any = {}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
cloned[key] = deepClone(obj[key])
}
}
return cloned
}
const original = {
name: 'Alice',
age: 25,
hobbies: ['reading', 'coding'],
address: {
street: '123 Main St',
city: 'Beijing'
}
}
const cloned = deepClone(original)
console.log(cloned)
// { name: 'Alice', age: 25, hobbies: ['reading', 'coding'], address: { street: '123 Main St', city: 'Beijing' } }
// 验证是深拷贝
original.address.city = 'Shanghai'
console.log(cloned.address.city) // 'Beijing'
注意事项
- 对象定义: 检查所有对象类型,包括数组、Date、RegExp等
- null检查: null不被认为是对象
- 函数检查: 函数不被认为是对象
- 类型守卫: 作为TypeScript类型守卫使用
- 性能: 检查速度很快,适合高频使用
与其他方法的区别
isObject()
: 检查是否为对象typeof value === 'object'
: 原生JavaScript检查(包括null)value !== null && typeof value === 'object'
: 排除null的对象检查Array.isArray()
: 检查是否为数组
实际应用场景
- 数据验证: 验证API响应中的对象字段
- 配置处理: 验证配置对象
- 表单处理: 验证表单数据对象
- 数据库操作: 验证数据库记录对象
- 事件处理: 验证事件对象
- 对象操作: 深度对象操作和比较