Skip to content

get

安全地获取对象的嵌套属性值,支持路径字符串和默认值。

基础用法

typescript
import { get } from 'radash'

const user = {
  name: 'Alice',
  address: {
    city: 'Beijing',
    country: 'China'
  }
}

console.log(get(user, 'name'))                    // 'Alice'
console.log(get(user, 'address.city'))           // 'Beijing'
console.log(get(user, 'address.zip', 'Unknown')) // 'Unknown'
console.log(get(user, 'nonexistent', 'Default')) // 'Default'

语法

typescript
function get<T = any>(
  obj: any,
  path: string | string[],
  fallback?: T
): T

参数

  • obj (any): 要查询的对象
  • path (string | string[]): 属性路径,可以是字符串(用点分隔)或数组
  • fallback (T, 可选): 当路径不存在时返回的默认值

返回值

返回指定路径的值,如果路径不存在则返回默认值。

示例

基本属性访问

typescript
import { get } from 'radash'

const user = {
  id: 1,
  name: 'Alice',
  email: 'alice@example.com'
}

console.log(get(user, 'name'))           // 'Alice'
console.log(get(user, 'email'))          // 'alice@example.com'
console.log(get(user, 'age', 25))        // 25 (默认值)

嵌套属性访问

typescript
import { get } from 'radash'

const user = {
  id: 1,
  profile: {
    name: 'Alice',
    address: {
      city: 'Beijing',
      country: 'China',
      details: {
        street: 'Main Street',
        zip: '100000'
      }
    }
  }
}

console.log(get(user, 'profile.name'))                    // 'Alice'
console.log(get(user, 'profile.address.city'))           // 'Beijing'
console.log(get(user, 'profile.address.details.street')) // 'Main Street'
console.log(get(user, 'profile.address.details.phone'))  // undefined

数组路径访问

typescript
import { get } from 'radash'

const user = {
  id: 1,
  profile: {
    name: 'Alice',
    hobbies: ['reading', 'swimming', 'coding']
  }
}

console.log(get(user, 'profile.hobbies.0'))     // 'reading'
console.log(get(user, 'profile.hobbies.1'))     // 'swimming'
console.log(get(user, 'profile.hobbies.5'))     // undefined
console.log(get(user, 'profile.hobbies.5', [])) // []

处理复杂对象

typescript
import { get } from 'radash'

const data = {
  users: [
    {
      id: 1,
      name: 'Alice',
      settings: {
        theme: 'dark',
        notifications: {
          email: true,
          push: false
        }
      }
    },
    {
      id: 2,
      name: 'Bob',
      settings: {
        theme: 'light',
        notifications: {
          email: false,
          push: true
        }
      }
    }
  ],
  config: {
    api: {
      baseUrl: 'https://api.example.com',
      timeout: 5000
    }
  }
}

console.log(get(data, 'users.0.name'))                    // 'Alice'
console.log(get(data, 'users.1.settings.theme'))         // 'light'
console.log(get(data, 'config.api.baseUrl'))             // 'https://api.example.com'
console.log(get(data, 'users.0.settings.notifications.push')) // false

使用数组路径

typescript
import { get } from 'radash'

const user = {
  profile: {
    name: 'Alice',
    address: {
      city: 'Beijing'
    }
  }
}

// 使用数组路径
console.log(get(user, ['profile', 'name']))           // 'Alice'
console.log(get(user, ['profile', 'address', 'city'])) // 'Beijing'
console.log(get(user, ['profile', 'age'], 25))        // 25

处理API响应

typescript
import { get } from 'radash'

function processApiResponse(response: any) {
  return {
    userId: get(response, 'data.user.id', 0),
    userName: get(response, 'data.user.name', 'Unknown'),
    userEmail: get(response, 'data.user.email', ''),
    userRole: get(response, 'data.user.role', 'user'),
    lastLogin: get(response, 'data.user.lastLogin', null)
  }
}

const apiResponse = {
  data: {
    user: {
      id: 123,
      name: 'Alice',
      email: 'alice@example.com'
      // role 和 lastLogin 不存在
    }
  }
}

const processed = processApiResponse(apiResponse)
console.log(processed)
// {
//   userId: 123,
//   userName: 'Alice',
//   userEmail: 'alice@example.com',
//   userRole: 'user',
//   lastLogin: null
// }

处理表单数据

typescript
import { get } from 'radash'

function processFormData(formData: FormData) {
  return {
    firstName: get(formData, 'user.firstName', ''),
    lastName: get(formData, 'user.lastName', ''),
    email: get(formData, 'user.email', ''),
    address: {
      street: get(formData, 'address.street', ''),
      city: get(formData, 'address.city', ''),
      zip: get(formData, 'address.zip', '')
    },
    preferences: {
      newsletter: get(formData, 'preferences.newsletter', false),
      notifications: get(formData, 'preferences.notifications', true)
    }
  }
}

// 模拟表单数据
const mockFormData = {
  user: {
    firstName: 'Alice',
    lastName: 'Smith',
    email: 'alice@example.com'
  },
  address: {
    street: '123 Main St',
    city: 'Beijing'
    // zip 不存在
  },
  preferences: {
    newsletter: true
    // notifications 不存在
  }
}

const processed = processFormData(mockFormData)
console.log(processed)

处理配置对象

typescript
import { get } from 'radash'

function parseConfig(config: any) {
  return {
    server: {
      port: get(config, 'server.port', 3000),
      host: get(config, 'server.host', 'localhost'),
      timeout: get(config, 'server.timeout', 5000)
    },
    database: {
      url: get(config, 'database.url', ''),
      pool: {
        min: get(config, 'database.pool.min', 1),
        max: get(config, 'database.pool.max', 10)
      }
    },
    features: {
      cache: get(config, 'features.cache', false),
      logging: get(config, 'features.logging', true)
    }
  }
}

const config = {
  server: {
    port: 8080,
    host: '0.0.0.0'
    // timeout 不存在
  },
  database: {
    url: 'postgresql://localhost:5432/mydb',
    pool: {
      min: 2
      // max 不存在
    }
  }
  // features 不存在
}

const parsed = parseConfig(config)
console.log(parsed)

处理嵌套数组

typescript
import { get } from 'radash'

const data = {
  departments: [
    {
      name: 'Engineering',
      employees: [
        { id: 1, name: 'Alice', role: 'Developer' },
        { id: 2, name: 'Bob', role: 'Manager' }
      ]
    },
    {
      name: 'Marketing',
      employees: [
        { id: 3, name: 'Charlie', role: 'Designer' }
      ]
    }
  ]
}

console.log(get(data, 'departments.0.name'))                    // 'Engineering'
console.log(get(data, 'departments.0.employees.0.name'))       // 'Alice'
console.log(get(data, 'departments.1.employees.0.role'))       // 'Designer'
console.log(get(data, 'departments.2.employees.0.name', 'N/A')) // 'N/A'

处理动态路径

typescript
import { get } from 'radash'

function getNestedValue(obj: any, pathParts: string[], defaultValue: any = undefined) {
  const path = pathParts.join('.')
  return get(obj, path, defaultValue)
}

const user = {
  profile: {
    personal: {
      name: 'Alice',
      age: 25
    },
    work: {
      company: 'Tech Corp',
      position: 'Developer'
    }
  }
}

console.log(getNestedValue(user, ['profile', 'personal', 'name'])) // 'Alice'
console.log(getNestedValue(user, ['profile', 'work', 'company']))  // 'Tech Corp'
console.log(getNestedValue(user, ['profile', 'personal', 'email'], 'N/A')) // 'N/A'

处理条件访问

typescript
import { get } from 'radash'

function getConditionalValue(obj: any, condition: string, truePath: string, falsePath: string) {
  const conditionValue = get(obj, condition, false)
  const path = conditionValue ? truePath : falsePath
  return get(obj, path, 'Default')
}

const user = {
  isPremium: true,
  premium: {
    features: ['advanced', 'priority']
  },
  basic: {
    features: ['standard']
  }
}

console.log(getConditionalValue(user, 'isPremium', 'premium.features', 'basic.features'))
// ['advanced', 'priority']

处理错误情况

typescript
import { get } from 'radash'

const data = {
  user: null,
  settings: undefined,
  config: {
    api: {
      url: 'https://api.example.com'
    }
  }
}

console.log(get(data, 'user.name', 'No user'))           // 'No user'
console.log(get(data, 'settings.theme', 'default'))      // 'default'
console.log(get(data, 'config.api.url'))                 // 'https://api.example.com'
console.log(get(data, 'config.api.timeout', 5000))       // 5000

处理复杂嵌套

typescript
import { get } from 'radash'

const complexData = {
  company: {
    departments: [
      {
        name: 'Engineering',
        teams: [
          {
            name: 'Frontend',
            members: [
              { id: 1, name: 'Alice', skills: ['React', 'TypeScript'] },
              { id: 2, name: 'Bob', skills: ['Vue', 'JavaScript'] }
            ]
          },
          {
            name: 'Backend',
            members: [
              { id: 3, name: 'Charlie', skills: ['Node.js', 'Python'] }
            ]
          }
        ]
      }
    ]
  }
}

console.log(get(complexData, 'company.departments.0.teams.0.members.0.name')) // 'Alice'
console.log(get(complexData, 'company.departments.0.teams.0.members.0.skills.0')) // 'React'
console.log(get(complexData, 'company.departments.0.teams.1.members.0.name')) // 'Charlie'

处理默认值类型

typescript
import { get } from 'radash'

const user = {
  name: 'Alice',
  preferences: {
    theme: 'dark'
  }
}

// 不同类型的默认值
console.log(get(user, 'age', 25))                    // 25 (number)
console.log(get(user, 'email', ''))                  // '' (string)
console.log(get(user, 'isActive', true))             // true (boolean)
console.log(get(user, 'tags', []))                   // [] (array)
console.log(get(user, 'settings', {}))               // {} (object)
console.log(get(user, 'lastLogin', null))            // null

注意事项

  1. 路径格式: 支持点分隔的字符串路径或数组路径
  2. 安全访问: 不会抛出错误,总是返回默认值或undefined
  3. 性能: 对于深层嵌套对象,性能良好
  4. 类型安全: 提供完整的TypeScript类型支持
  5. 默认值: 当路径不存在时返回指定的默认值

与其他方法的区别

  • obj?.prop: 只支持单层属性访问
  • lodash.get(): 类似功能,但radash的get更轻量
  • get(): radash提供的安全属性访问方法

实际应用场景

  1. API响应处理: 安全访问嵌套的API数据
  2. 配置管理: 访问配置文件中的嵌套设置
  3. 表单处理: 处理复杂的表单数据结构
  4. 数据转换: 安全地提取嵌套数据
  5. 错误处理: 避免访问不存在的属性时出错

Released under the MIT License.