JS 解构赋值默认值:为缺失的属性/元素设置默认值

各位观众老爷们,晚上好!(拱手)

今天咱们不聊风花雪月,就来唠唠JavaScript里一个既实用又容易被忽略的小技巧:解构赋值的默认值。这玩意儿就像是瑞士军刀里的起子,平时不显山不露水,关键时刻能帮你打开一个新世界的大门。

啥是解构赋值?

先简单回顾一下解构赋值。简单来说,它就是把对象或数组里的值,像拆包裹一样,直接赋值给对应的变量。比方说:

const person = {
  name: '张三',
  age: 30,
  city: '北京'
};

const { name, age, city } = person;

console.log(name); // 输出:张三
console.log(age);  // 输出:30
console.log(city); // 输出:北京

看,是不是很方便?不用 person.nameperson.age 这样一层层访问,直接一股脑儿全拿出来了。数组也一样:

const numbers = [1, 2, 3];

const [first, second, third] = numbers;

console.log(first);  // 输出:1
console.log(second); // 输出:2
console.log(third);  // 输出:3

默认值:未雨绸缪,避免undefined

但是,人生不如意事十之八九,解构的时候,万一对象或数组里没有对应的属性或元素怎么办?这时候,如果没有做任何处理,变量就会变成 undefined。就像你兴冲冲地跑去取快递,结果发现快递员压根没给你发货一样,空欢喜一场。

const person = {
  name: '张三',
  age: 30,
};

const { name, age, city } = person;

console.log(city); // 输出:undefined

city 这个属性在 person 对象里压根不存在,所以 city 变量就成了 undefined。这在某些情况下可能会导致程序出错。

这时候,默认值就派上用场了。它可以让你在属性或元素缺失的时候,给变量一个预设的值,避免 undefined 的出现。

对象解构的默认值

给对象解构设置默认值的语法很简单,就是在变量后面加上 = 和默认值:

const person = {
  name: '张三',
  age: 30,
};

const { name, age, city = '未知' } = person;

console.log(city); // 输出:未知

现在,即使 person 对象里没有 city 属性,city 变量也不会是 undefined 了,而是变成了我们预设的 '未知'

还可以给多个属性设置默认值:

const person = {
  name: '张三',
};

const { name, age = 18, city = '未知' } = person;

console.log(age);  // 输出:18
console.log(city); // 输出:未知

数组解构的默认值

数组解构设置默认值的方式和对象解构类似:

const numbers = [1, 2];

const [first, second, third = 3] = numbers;

console.log(third); // 输出:3

numbers 数组只有两个元素,所以 third 变量会使用默认值 3

默认值的注意事项

  • 只有当属性或元素的值严格等于 undefined 时,默认值才会生效。 也就是说,如果属性或元素的值是 null,默认值是不会生效的。

    const person = {
      name: '张三',
      city: null
    };
    
    const { city = '未知' } = person;
    
    console.log(city); // 输出:null

    因为 person.city 的值是 null,不是 undefined,所以 city 变量的值仍然是 null,而不是 '未知'

  • 默认值可以是任何有效的 JavaScript 表达式。 这意味着你可以用函数调用、三元运算符等等来作为默认值。

    const getDefaultCity = () => {
      console.log('正在获取默认城市...');
      return '上海';
    };
    
    const person = {
      name: '张三',
    };
    
    const { city = getDefaultCity() } = person;
    
    console.log(city); // 输出:上海

    这个例子中,getDefaultCity() 函数只会在 city 属性不存在的时候才会被调用。

  • 可以结合剩余参数来使用默认值。

    const numbers = [1];
    
    const [first, ...rest] = numbers;
    
    console.log(first); // 输出:1
    console.log(rest);  // 输出:[]

    如果 numbers 数组只有一个元素,rest 变量会是一个空数组。 如果想给rest 设置默认值,可以这样做

     const numbers = [1];
    
        const [first, ...rest = [2,3,4]] = numbers;
    
        console.log(first); // 输出:1
        console.log(rest);  // 输出:[]  注意! 这里rest仍然是 [], 因为rest已经成功赋值为空数组了。默认值只在完全未赋值的时候才生效

默认值的应用场景

默认值在很多场景下都非常有用:

  1. 处理 API 返回的数据。 API 返回的数据结构可能会发生变化,某些属性可能会缺失。使用默认值可以保证你的代码在数据不完整的情况下也能正常运行。

    // 假设 API 返回的数据
    const apiResponse = {
      name: '李四',
      age: 25,
    };
    
    const { name, age, city = '未知' } = apiResponse;
    
    console.log(`姓名:${name},年龄:${age},城市:${city}`);
    // 输出:姓名:李四,年龄:25,城市:未知
  2. 处理用户输入的数据。 用户可能没有填写所有表单字段,使用默认值可以给缺失的字段提供一个合理的值。

    // 假设用户输入的数据
    const userInput = {
      name: '王五',
    };
    
    const { name, age = 18, email = '暂无' } = userInput;
    
    console.log(`姓名:${name},年龄:${age},邮箱:${email}`);
    // 输出:姓名:王五,年龄:18,邮箱:暂无
  3. 简化函数参数。 可以使用默认值来为函数参数提供默认值,这样调用函数时可以省略某些参数。

    function greet(name, greeting = '你好') {
      console.log(`${greeting},${name}!`);
    }
    
    greet('赵六'); // 输出:你好,赵六!
    greet('钱七', '早上好'); // 输出:早上好,钱七!

更高级的用法:默认值与函数结合

默认值不仅可以是简单的数据,还可以是一个函数。这为我们提供了更大的灵活性。

const config = {
  apiUrl: 'https://example.com/api',
};

const fetchData = (url, apiKey = () => config.apiKey || 'DEFAULT_API_KEY') => {
  const actualApiKey = apiKey(); // 调用函数获取apiKey
  console.log(`Using API Key: ${actualApiKey}`);
  // 模拟网络请求
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ data: `Data from ${url} with API Key: ${actualApiKey}` });
    }, 100);
  });
};

// 使用默认API Key
fetchData('/users')
  .then(result => console.log(result.data));
// 如果config对象没有apiKey属性,则使用'DEFAULT_API_KEY'

config.apiKey = 'YOUR_API_KEY'; // 设置apiKey
// 使用config中的API Key
fetchData('/products')
  .then(result => console.log(result.data));

在这个例子中,apiKey 参数的默认值是一个匿名函数。这个函数会尝试从 config 对象中获取 apiKey,如果 config 对象没有 apiKey 属性,则返回 'DEFAULT_API_KEY'。这样,我们就可以在调用 fetchData 函数时,根据需要选择是否传入 apiKey 参数。

默认值与计算属性名

解构赋值还支持计算属性名,我们可以将默认值和计算属性名结合起来使用。

const key = 'dynamicKey';
const obj = {};

const { [key]: dynamicValue = 'default' } = obj;

console.log(dynamicValue); // 输出: default

const obj2 = { dynamicKey: 'actualValue' };

const { [key]: dynamicValue2 = 'default' } = obj2;

console.log(dynamicValue2); // 输出: actualValue

在这个例子中,我们使用变量 key 作为属性名进行解构,并为 dynamicValue 设置了默认值 'default'

总结

解构赋值的默认值是一个非常实用的技巧,它可以帮助你编写更健壮、更简洁的代码。掌握它,就像掌握了一门防身术,能在关键时刻保护你的程序免受 undefined 的侵害。

表格总结

特性 对象解构 数组解构
语法 const { prop = defaultValue } = obj; const [elem = defaultValue] = arr;
生效条件 属性值为 undefined 时生效 元素值为 undefined 时生效
默认值类型 可以是任何 JavaScript 表达式 可以是任何 JavaScript 表达式
应用场景 处理 API 数据、用户输入、简化函数参数等 处理 API 数据、用户输入、简化函数参数等
特殊用法 可与计算属性名结合使用 可结合剩余参数使用

举例说明

场景 代码示例 说明
API数据处理 const { data, error = null } = apiResponse; 如果 API 返回的数据中没有 error 属性,则 error 变量的值为 null
用户输入处理 const { name, age = 18 } = userInput; 如果用户没有输入年龄,则 age 变量的值为 18
函数参数默认值 function greet(name, greeting = '你好') { ... } 如果调用 greet 函数时没有传入 greeting 参数,则使用默认值 '你好'
数组默认值 const [first, second, third = 0] = numbers; 如果数组 numbers 只有两个元素,则 third 变量的值为 0
函数返回值 const getCoordinates = () => ({ x: 10, y: undefined });
const { x, y = 0 } = getCoordinates();
如果 getCoordinates 函数返回的对象的 y 属性为 undefined,则 y 变量的值为 0

好了,今天的分享就到这里。希望大家以后在写代码的时候,能想起这个小技巧,让你的代码更加健壮、优雅。下次有机会再和大家聊聊其他有趣的 JavaScript 知识。散会!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注