JavaScript常用技巧专题三

2023-12-20 07:08:38


一、处理默认参数

JavaScript中处理默认参数是一个常见的编程场景,不同水平的开发者在这方面的处理方法可能大相径庭。今天,我们来看看初学者和专业开发者在处理默认参数时的不同方式。

初学者:使用逻辑或运算符

初学者在处理默认参数时,常常倾向于使用逻辑或运算符(||)。例如,一个打招呼的函数可能会这样写:

function greet(name) {
  name = name || 'Guest';
  console.log('Hello, ' + name + '!');
}

这种方法简单直观,但它有一个潜在的问题:当传递的参数是false值(如0、空字符串等)时,逻辑或运算符会错误地将这些值视为未定义或空,从而导致默认值被错误使用。

专家:直接在函数签名中指定默认值

与此相比,经验丰富的开发者更倾向于直接在函数签名中指定默认参数。这样做不仅代码更加简洁,而且更加安全和直观。同样的打招呼函数可以被重写为:

function greet(name = 'Guest') {
  console.log(`Hello, ${name}!`);
}

在这个版本中,如果调用greet函数时没有提供参数,或者参数为undefinedname将默认为Guest。这种方法的优点在于它更加稳健,能够正确处理各种类型的参数,包括false值。

了解并合理使用默认参数是提升JavaScript编程技能的一个重要方面。对于初学者来说,这是一个学习如何编写更稳健、更可读代码的好机会。而对于专业开发者,恰当地利用函数签名中的默认参数,不仅可以简化代码,还可以提高代码的健壮性。这是一种既实用又优雅的编程实践,值得每个JavaScript开发者掌握。

二、字符串的拼接

JavaScript中,字符串的拼接和处理是一个非常基础且常见的任务。不同水平的开发者在处理字符串时的方法可能截然不同,尤其是当涉及到字符串拼接时。

初学者:使用传统的字符串连接

对于初学者来说,他们可能更习惯于使用传统的+运算符来拼接字符串。例如:

const name = 'Alice';
console.log('Hello, ' + name + '!');

这种方法简单直观,但在处理包含多个变量的复杂字符串时,它可能变得笨拙和难以阅读。随着字符串拼接的增多,代码的可读性和维护性逐渐降低。

专家:采用模板字面量

相比之下,经验丰富的JavaScript开发者更倾向于使用ES6引入的模板字面量(Template Literals)。模板字面量使用反引号``包围字符串,并通过${}插入变量,使得字符串拼接变得更加简洁和直观。例如:

const name = 'Alice';
console.log(`Hello, ${name}!`);

在这种写法中,字符串内的变量和表达式被清晰地标识出来,提高了代码的可读性和表达性。模板字面量特别适合用于构建复杂的字符串,或者当字符串中需要插入多个变量和表达式时。

模板字面量是JavaScript中一个非常强大和实用的特性,它不仅使得字符串处理更加简单和直观,而且显著提升了代码的可读性和维护性。对于初学者来说,掌握模板字面量是提高编码效率的一个重要步骤。对于经验丰富的开发者而言,恰当地运用模板字面量能够使代码更加简洁和优雅。在现代JavaScript开发中,模板字面量已成为处理字符串的首选方法。

三、 对象解构

JavaScript中,对象解构是ES6引入的一项功能,它极大地简化了从对象中提取属性的过程。这项技术在不同水平的开发者之间显示出显著的使用差异。

初学者:单独变量赋值

初学者在从对象中提取属性时,可能倾向于使用传统的单独变量赋值的方法。例如:

const person = { name: 'John', age: 30 };
const name = person.name;
const age = person.age;

这种方法虽然直接明了,但在处理具有多个属性的对象时可能会导致代码重复,使得代码冗长并且维护起来比较困难。

专家:使用对象解构

相比之下,经验丰富的JavaScript开发者会使用对象解构来提取属性,这是一种更简洁、更高效的方法。例如:

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

在这个例子中,nameage变量是通过解构person对象一次性创建并赋值的。这种方式不仅减少了代码量,而且提高了代码的可读性和维护性。

对象解构是一种强大的编程技巧,它使得从对象中提取多个属性变得既简单又高效。对于初学者来说,掌握对象解构是一个提高代码质量和效率的重要步骤。而对于经验丰富的开发者,恰当地运用对象解构可以大幅简化代码结构,使代码更加整洁和可维护。在现代JavaScript编程实践中,对象解构已经成为了一种常用且推荐的模式。

四、 使用map()进行数组转换

JavaScript中,数组的转换和处理是常见的编程任务之一。对于如何实现数组元素的转换,不同水平的开发者可能会采用不同的方法。

初学者:使用循环进行数组转换

初学者在进行数组转换时,可能会倾向于使用传统的循环。例如,将一个数字数组中的每个元素平方,可能会这样写:

const numbers = [1, 2, 3];
const squaredNumbers = [];
for (let i = 0; i < numbers.length; i++) {
  squaredNumbers.push(numbers[i] * numbers[i]);
}

这种方法虽然可以实现目标,但当数组处理变得更加复杂时,这种代码可能会变得冗长且容易出错。

专家:使用map()方法进行数组转换

与此相比,经验丰富的JavaScript开发者更喜欢使用map()方法来进行数组转换。map()是一个数组的高阶函数,它可以对数组中的每个元素执行一个给定的函数,并返回一个新的数组,这些新数组的元素是原始数组元素经过函数处理后的结果。例如,上述的平方操作可以重写为:

const numbers = [1, 2, 3];
const squaredNumbers = numbers.map(number => number * number);

使用map()方法,代码不仅更加简洁,而且更加表达性和易于阅读。此外,map()方法符合函数式编程的原则,使得代码更容易理解和维护。

五、使用 Promise 处理异步操作

JavaScript编程中,异步操作的处理是一个复杂但至关重要的主题。不同水平的开发者在处理异步操作时,通常会采取不同的方法。

初学者:使用Promise和链式调用

初学者在处理异步操作时,可能会使用Promise结合链式调用(.then()和.catch())。例如,从某个API获取数据的函数可能会这样写:

function fetchData() {
  return new Promise((resolve, reject) => {
    // Asynchronous operation
    if (success) {
      resolve(data);
    } else {
      reject(error);
    }
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

这种方法是处理异步操作的一种标准方式,但可能会导致所谓的“回调地狱”(Callback Hell),尤其是在处理多个嵌套异步操作时,代码可读性和维护性大打折扣。

专家:使用async/await

相比之下,经验丰富的开发者倾向于使用async/await,这是一种更现代的异步处理方式。async/await使得异步代码看起来更像是同步代码,这样不仅改善了代码结构,也使得错误处理变得更加直接。同样的数据获取函数可以被重写为:

async function fetchData() {
  try {
    const data = await fetch('https://api.example.com/data');
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

fetchData();

在这种写法中,await关键字使得异步操作的结果可以以同步方式获取,极大地提高了代码的可读性和简洁性。此外,通过结合try/catch,错误处理变得更加直接和清晰。

了解并掌握不同的异步处理方式是成为一个JavaScript专家的关键步骤。对于初学者来说,理解并能够使用Promise是基础,而掌握async/await则是进阶。对于经验丰富的开发者,合理运用async/await不仅可以简化代码结构,还能提高代码的可读性和可维护性。在现代JavaScript开发中,async/await已成为处理异步操作的首选方法。

六、处理多种条件选择

JavaScript中,处理多重条件是一个常见的编程场景。不同水平的开发者可能会采用不同的方式来处理这种情况。

初学者:使用多个if-else语句

对于初学者来说,他们可能会倾向于使用多个if-else语句来处理不同的条件。例如,基于一个值来设置不同的结果:

const value = 3;
let result;
if (value === 1) {
  result = 'One';
} else if (value === 2) {
  result = 'Two';
} else {
  result = 'Other';
}

这种方法虽然直观,但当条件数量增加时,代码可能会变得冗长且难以维护。过多的if-else语句会使代码看起来杂乱,也增加了理解和维护的难度。

专家:使用三元运算符

相比之下,经验丰富的开发者可能会使用三元运算符来处理这种情况。三元运算符提供了一种更加紧凑和可读的方式来处理多重条件。例如,上述的代码可以被重写为:

const value = 3;
const result = value === 1 ? 'One' : value === 2 ? 'Two' : 'Other';

使用三元运算符,代码更加简洁,可读性也得到提升。虽然在处理多个条件时,三元运算符可能会导致一定的嵌套,但它通常比多个if-else语句更加简洁和清晰。

在处理多重条件时,合理选择条件处理方式对于保持代码的简洁性和可维护性至关重要。对于初学者而言,理解不同的条件处理方式并选择最适合当前场景的方法是一个重要的学习过程。对于经验丰富的开发者,使用三元运算符或其他更高级的条件处理技术可以大大简化代码,提高代码的可读性和可维护性。在现代JavaScript编程中,寻找并实现最有效的条件处理策略是提高编码效率和代码质量的关键。

七、 使用集合

JavaScript中,处理数组以创建唯一值集合是一个常见的任务。不同水平的开发者可能会使用不同的方法来实现这一目标。

初学者:使用循环和条件判断

初学者在创建唯一值集合时,可能会倾向于使用循环结合条件判断。例如,从一个数组中提取唯一元素可能会这样写:

const uniqueNumbers = [];
const numbers = [1, 2, 2, 3, 4, 4, 5];
for (let i = 0; i < numbers.length; i++) {
  if (!uniqueNumbers.includes(numbers[i])) {
    uniqueNumbers.push(numbers[i]);
  }
}

这种方法虽然能够实现目标,但在处理大型数组或者复杂的数据结构时可能效率不高。每次检查是否包含一个元素时都需要遍历整个uniqueNumbers数组,这在性能上是不理想的。

专家:使用Set对象和展开运算符

相比之下,经验丰富的JavaScript开发者更喜欢使用Set对象和展开运算符…来创建唯一值集合。Set对象是一个集合类型,它自动保证了内部元素的唯一性。例如,上述的代码可以被重写为:

const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];

在这个例子中,new Set(numbers)创建了一个包含所有唯一数字的集合,然后使用展开运算符…将其转换成数组。这种方法不仅代码更简洁,而且在性能上也更优,尤其是在处理大型数据集时。

使用现代JavaScript的特性,如Set对象和展开运算符,可以显著简化代码并提高性能。对于初学者来说,学习并使用这些特性是提高编码效率和代码质量的重要一步。对于经验丰富的开发者,恰当地利用这些强大的工具可以使代码更加简洁、高效和优雅。在处理需要唯一值集合的场景时,Set对象提供了一个非常方便和高效的解决方案。

八、使用bind()函数

JavaScript中,正确处理函数上下文(this关键字的指向)是一个关键的编程技巧。不同水平的开发者可能会使用不同的方法来绑定函数上下文。

初学者:使用call()apply()手动绑定

初学者在处理函数上下文时,可能会倾向于使用call()apply()方法来手动绑定。这种方法虽然有效,但可能导致代码冗长和重复。例如,将一个打招呼的函数绑定到一个特定对象上:

function greet() {
  console.log('Hello, ' + this.name + '!');
}
const person = { name: 'Alice' };
const boundGreet = function() {
  greet.call(person);
}
boundGreet()

在这个例子中,每次调用boundGreet时,都需要使用call()来确保greet函数中的this正确指向person对象。

专家:使用bind()方法

与此相比,经验丰富的开发者更喜欢使用bind()方法来设置函数的上下文。bind()方法创建一个新函数,这个新函数在被调用时将其this关键字设置为提供的值,从而永久绑定函数上下文。例如:

function greet() {
  console.log('Hello, ' + this.name + '!');
}
const person = { name: 'Alice' };
const boundGreet = greet.bind(person);
boundGreet();

在这种写法中,greet.bind(person)返回一个新函数,这个新函数的this被永久绑定到person对象上。这样,每次调用boundGreet时,就无需再担心this的指向问题,代码更加简洁和易于理解。

理解并合理使用JavaScript中的函数绑定方法是提高编码技巧的重要一步。对于初学者来说,学习如何使用call()apply()bind()是理解函数上下文的基础。而对于经验丰富的开发者,合理运用bind()方法可以使代码更加简洁和清晰,提高代码的可读性和可维护性。在处理需要特定上下文的函数时,bind()方法提供了一个优雅且高效的解决方案。

九、使用 Object.assign() 进行对象合并

JavaScript中,对象合并是一项常见的任务,不同水平的开发者可能会采用不同的方法来实现这一功能。

初学者:使用循环手动合并对象

初学者在合并对象时,可能会倾向于使用循环来逐个复制属性。这种方法虽然直观,但可能会导致代码冗长且容易出错。例如,合并两个对象的代码可能如下所示:

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = {};
for (let key in obj1) {
  merged[key] = obj1[key];
}
for (let key in obj2) {
  merged[key] = obj2[key];
}

在这个例子中,需要分别遍历两个对象,并将每个属性手动复制到新对象中。这种方法在处理更复杂的对象或更多的对象时会变得越发繁琐。

专家:使用Object.assign()进行对象合并

相比之下,经验丰富的开发者更喜欢使用Object.assign()方法来实现对象的合并。这个方法可以将所有可枚举的自有属性从一个或多个源对象复制到目标对象,并返回目标对象。例如,合并对象的操作可以简化为:

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = Object.assign({}, obj1, obj2);

在这种写法中,Object.assign()方法创建了一个新对象,并将obj1obj2中的属性复制到这个新对象中。这不仅减少了代码量,而且提高了代码的可读性和效率。

掌握并运用Object.assign()方法是JavaScript编程中的一个重要技巧,尤其是在处理对象合并的场景中。对于初学者而言,学习这个方法是提高编程效率和代码质量的重要一步。对于经验丰富的开发者,恰当地使用Object.assign()不仅可以简化代码,还能提高代码的执行效率。在现代JavaScript开发实践中,Object.assign()是处理对象合并的首选方法。

十、使用 Array.from() 进行映射和过滤

JavaScript中,对数组进行映射(Mapping)和过滤(Filtering)是常见的数据处理操作。不同水平的开发者可能会采用不同的方法来实现这些功能。

初学者:分别使用map()filter()

初学者在对数组进行处理时,可能会倾向于分别使用map()filter()方法。这种方法虽然易于理解,但可能会导致生成中间数组,从而降低代码效率。例如,对数组中的数字先进行平方,然后过滤出偶数,可能会这样写:

const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(number => number * number);
const evenSquaredNumbers = squaredNumbers.filter(number => number % 2 === 0);

在这个例子中,首先通过map()创建了一个包含平方数的中间数组,然后通过filter()从中筛选出偶数。

专家:使用Array.from()结合映射函数

相比之下,经验丰富的JavaScript开发者可能会使用Array.from()结合映射函数来同时完成映射和过滤。这种方法可以在单个步骤中完成两个操作,提高代码的效率和简洁性。例如:

const numbers = [1, 2, 3, 4, 5];
const evenSquaredNumbers = Array.from(numbers, number => number * number).filter(number => number % 2 === 0);

在这种写法中,Array.from()不仅创建了一个新数组,还允许在创建数组的同时对每个元素应用映射函数。然后,可以直接在结果上应用filter(),从而避免了创建中间数组。

合理地使用高效的数组处理方法是提高JavaScript代码质量和性能的关键。对于初学者来说,学习和掌握数组的各种方法,如map()filter()是基础。而对于经验丰富的开发者,通过技巧如使用Array.from()结合映射函数来优化代码,不仅可以提高代码的执行效率,还能提高代码的可读性和维护性。在现代JavaScript开发中,寻找并应用这样的优化技巧是非常重要的。

十一、使用剩余参数

JavaScript中,处理可变数量的参数是一个常见的需求。不同水平的开发者可能会采用不同的方法来实现这一功能。

初学者:使用数组处理可变参数

初学者在处理可变数量的参数时,可能会倾向于使用数组。例如,编写一个求和函数,可能会这样写:

function sum(a, b) {
  const numbers = [a, b];
  return numbers.reduce((total, num) => total + num, 0);
}

在这个例子中,函数仅接受两个参数,然后将它们放入数组中进行处理。这种方法在参数数量固定时可行,但当参数数量可变时,代码就显得笨拙且不直观。

专家:使用剩余参数(Rest Parameter

相比之下,经验丰富的JavaScript开发者可能会使用剩余参数(Rest Parameter)来处理可变数量的参数。剩余参数语法允许我们将一个不定数量的参数表示为一个数组。例如,上述的求和函数可以重写为:

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

在这种写法中,使用...numbers表示函数可以接受任意数量的参数,这些参数会被自动组成一个数组numbers。然后,通过reduce()方法对这些参数求和。这种方法不仅代码更简洁,而且更加直观和灵活。

理解并合理使用剩余参数是JavaScript编程中的一个重要技巧。对于初学者而言,学习如何使用剩余参数是提高代码灵活性和可读性的一个重要步骤。而对于经验丰富的开发者,正确运用剩余参数可以使函数更加通用和强大,同时简化代码的书写。在现代JavaScript开发中,剩余参数是处理可变数量参数的首选方法。

十二、使用 Array.prototype.reduce() 进行复杂操作

JavaScript中,处理复杂的数组操作是一个常见的需求。不同水平的开发者可能会采用不同的方法来实现这些操作。

初学者:使用循环进行复杂操作

初学者在执行诸如数组求和这样的复杂操作时,可能会倾向于使用传统的循环。例如,计算一个数组中所有元素的和可能会这样写:

const numbers = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}

这种方法是有效的,但在处理更复杂的操作时,代码可能会变得冗长且难以维护。

专家:使用Array.prototype.reduce()进行复杂操作

相比之下,经验丰富的JavaScript开发者更倾向于使用Array.prototype.reduce()方法来处理这类复杂操作。reduce()方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。例如,上述求和操作可以重写为:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, num) => total + num, 0);

在这种写法中,reduce()方法接收一个回调函数,该函数将数组中的每个元素累加到一个累积变量total中。这种方法不仅代码更加简洁,而且提高了代码的可读性和表达性,尤其适用于更复杂的数组处理任务。

Array.prototype.reduce()JavaScript中一个非常强大的工具,适用于各种复杂的数组操作。对于初学者来说,掌握reduce()是理解和运用函数式编程概念的一个重要步骤。而对于经验丰富的开发者,合理地使用reduce()不仅可以简化代码,还能提高代码的执行效率和可维护性。在现代JavaScript编程实践中,reduce()是处理复杂数组操作的首选方法。

十三、处理日期和时间

初学者:单独处理日期和时间组件

初学者在处理日期和时间时,可能会倾向于分别获取年、月、日等信息。例如,获取当前日期并分别提取年、月、日可能会这样写:

const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份从0开始,所以需要加1
const day = now.getDate();

这种方法虽然直接,但当需要处理多个日期组件时,代码可能会变得冗长且易于出错,特别是在进行更复杂的日期操作时。

专家:使用数组解构处理日期和时间

相比之下,经验丰富的JavaScript开发者更倾向于使用数组解构来处理日期和时间。数组解构可以同时提取多个值,使得代码更加简洁和易读。例如,上述代码可以重写为:

const now = new Date();
const [year, month, day] = [now.getFullYear(), now.getMonth() + 1, now.getDate()];

在这种写法中,通过数组解构一次性提取出年、月、日,并分别赋值给对应的变量。这种方法减少了冗余代码,提高了代码的可读性和维护性。

JavaScript中,合理使用数组解构可以显著提高处理日期和时间的效率和代码质量。对于初学者而言,理解并掌握如何高效处理日期和时间是提高编程技能的重要步骤。对于经验丰富的开发者,运用数组解构等现代JavaScript特性可以使代码更加简洁、高效和易于维护。在处理涉及多个日期组件的复杂操作时,这种方法尤其有用。

十四、使用 JSON 数据

JavaScript中,处理JSONJavaScript Object Notation)数据是一个非常常见的任务,尤其是在网络编程和数据交换中。不同水平的开发者在处理JSON数据时可能会采取不同的方法。

初学者:直接使用JSON.parse()

初学者在处理JSON数据时,可能会直接使用JSON.parse()来解析JSON字符串。例如,解析一个包含个人信息的JSON字符串可能会这样写:

const jsonData = '{"name": "John", "age": 30}';
const parsedData = JSON.parse(jsonData);
console.log(parsedData.name); // 输出: 'John'

这种方法虽然直接,但没有处理解析过程中可能出现的错误。如果JSON数据格式不正确,JSON.parse()会抛出一个错误,可能导致程序崩溃或不可预测的行为。

专家:在try...catch块中处理JSON解析

相比之下,经验丰富的JavaScript开发者会在try...catch块中进行JSON解析,以优雅地处理可能出现的错误。这样做不仅提高了代码的健壮性,还防止了因格式错误的数据导致的应用程序崩溃。例如:

const jsonData = '{"name": "John", "age": 30}';
try {
  const parsedData = JSON.parse(jsonData);
  console.log(parsedData.name); // 输出: 'John'
} catch (error) {
  console.error('Invalid JSON data:', error);
}

在这种写法中,如果解析过程中出现错误,控制流将跳转到catch块,可以在其中处理错误,例如打印错误消息或采取其他措施。这样的错误处理机制使得代码更加健壮和可靠。

正确和安全地处理JSON数据是现代JavaScript编程中的一个重要方面。对于初学者来说,学习如何正确解析和处理JSON数据是非常重要的。而对于经验丰富的开发者,合理地使用错误处理机制,如try...catch块,可以防止因数据问题导致的程序崩溃,确保应用程序的稳定性和可靠性。在处理JSON数据时,这种健壮的错误处理策略是非常关键的。

十五、使用模块进行代码组织

在现代JavaScript开发中,合理地组织和模块化代码是非常重要的,尤其是对于大型或复杂的项目。不同水平的开发者可能会以不同的方式组织他们的代码。

初学者:在单个文件中编写所有代码

初学者在编写JavaScript时,可能会倾向于将所有代码写在单个文件中。例如,他们可能会这样组织代码:

script1.js

function greet(name) {
  console.log('Hello, ' + name + '!');
}
greet('Alice');

script2.js

function calculateSquare(num) {
  return num * num;
}
console.log(calculateSquare(3));

这种方法在小型项目或简单脚本中可能可行,但随着项目规模的增长,这种方式可能导致代码组织混乱和维护困难。

专家:使用模块化代码组织

相比之下,经验丰富的JavaScript开发者会使用模块来组织代码。他们会将不同的功能分散到不同的文件中,并通过importexport语句来共享这些功能。这种方法不仅提高了代码的可维护性,也使得代码结构更清晰。例如:

greetings.js

export function greet(name) {
  console.log('Hello, ' + name + '!');
}

calculations.js

export function calculateSquare(num) {
  return num * num;
}

main.js

import { greet } from './greetings';
import { calculateSquare } from './calculations';
greet('Alice');
console.log(calculateSquare(3));

在这种写法中,每个文件负责一个特定的功能或逻辑,通过模块导出和导入实现代码的复用和分离。这种模块化的方法使得代码更加组织化,便于维护和扩展。

模块化是现代JavaScript开发中一个非常重要的概念。对于初学者来说,理解并开始使用模块化是提高代码质量和项目可维护性的关键步骤。对于经验丰富的开发者,合理地使用模块化可以有效地组织代码,提高代码的可读性和可维护性,尤其在大型项目中这一点尤为重要。在现代JavaScript项目中,模块化是保持代码清晰和有序的首选方式。

十六、总结

通过了解初学者和经验丰富的开发者在处理JavaScript各种技巧上的不同方法,你可以将自己的编码风格从新手转变为专业人士。采纳这些技巧不仅能提高你的代码效率,还能增强代码的可读性、可维护性以及整体的开发体验。

效率: 通过使用现代JavaScript特性,如箭头函数、map()reduce()等,你可以写出更简洁高效的代码。

可读性: 利用模板字符串、解构赋值等技巧,可以使代码更加直观和易于理解。

可维护性: 采用模块化、函数式编程概念等,可以帮助你构建更加组织化且易于维护的代码结构。

十七、最后

本人每篇文章都是一字一句码出来,希望对大家有所帮助,多提提意见。顺手来个三连击,点赞👍收藏💖关注?,一起加油?

文章来源:https://blog.csdn.net/u012804440/article/details/135042881
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。