提高代码质量的 11 个 JavaScript 核心函数

它不在乎你是使用后端还是前端(甚至是宇宙飞船!),JavaScript可以在任何地方使用,因为它是一种非常灵活的语言。它具有核心的函数式编程模式以及类,它与其他“类c”语言的相似性使每个开发人员都可以轻松地过渡。

如果你想提升你的JavaScript技能,我建议你学习、练习和掌握这门语言中以下非常重要的核心函数。你不需要每个函数来解决大多数问题,但在某些情况下,它们可以帮助你避免繁重的工作,而在其他情况下,它们将减少你必须编写的代码量。

1. map()

map()是JavaScript中最重要的函数之一!此外,它也是给学习JavaScript的人带来最大麻烦的一个函数。之所以会这样,是因为这个函数的工作方式来自于大多数开发人员不熟悉的函数式编程。在我们有偏见的大脑看来,这似乎很奇怪,甚至是错误的。

函数map()非常简单。它将自己附加到一个数组,并将每个元素转换为其他元素,从而得到一个新数组。这种转换是通过map括号中提供的匿名函数完成的。

这就是地图所做的一切!

一开始,map()的语法可能需要一些时间来适应,但掌握它之后,你将成为使用JavaScript的最好朋友。

为什么要使用map()?

例如,假设我们记录了上周每一天喷泉中的水量并将其存储在一个数组中。 在周末,您被告知测量工具不够准确,水量比应有的少了 3.2 升。

使用 map() 函数,您可以通过以下方式轻松解决此问题:

const dailyReadings = [34.2, 35.4, 40.1, 35.2, 33.5, 36.5, 38.7];

const correctedDailyReadings = dailyReadings.map(day => day + 3.2);

console.log(correctedDailyReadings); //gives [37.4, 38.6, 43.3, 38.4, 36.7, 39.7, 41.9]

当您从数组创建 DOM 元素列表时,您可以在 React 的世界中找到另一个非常实用的示例。 这是 React 中的常见模式,将通过这段代码实现:

export default({articles}) => {
    return links.map(article => {
        return (
            
                {article.name}
                {article.description}
            
        );
    });
};

现在你可以争辩说 map() 只不过是 for 循环的另一种实现,你是对的,但请注意,也许这是你受过面向对象训练的头脑提出了这个论点。

2. filter()

filter() 是一个非常有用的 JavaScript 函数,您可以在许多情况下使用它,因为它根据给定的规则/逻辑过滤数组。 此规则/逻辑将作为匿名函数提供。

为了展示 filter() 是如何工作的,我们可以重用之前的喷泉示例。 假设数组包含喷泉中存储的水量(这次测量工具按预期工作)。 现在,我们想知道该量低于 36 升的频率。 这可以使用 filter() 函数来实现:

const dailyReadings = [34.2, 35.4, 40.1, 35.2, 33.5, 36.5, 38.7];

const daysWithLowAmount = dailyReadings.filter(day => {
    return day < 36
});

console.log("Days with low amount of water: " + daysWithLowAmount.length); // 4
console.log(daysWithLowAmount); // [34.2, 35.4, 35.2, 33.5]

重要的是,您传递给 filter() 的匿名函数必须返回一个布尔值:true 或 false。 filter() 函数使用布尔表达式来确定是否应将值插入新生成的数组中。

在匿名函数中,您可以实现任意数量的复杂逻辑来过滤数据; 您可以读取用户输入、进行任何 API 调用等,只要最后返回一个布尔值即可。

注意:请记住 filter() 总是返回一个数组。 如果过滤后的数据为空,也是如此。 这通常会导致代码片段中出现细微的错误,因为 filter() 是这样使用的:

const dailyReadings = [34.2, 35.4, 40.1, 35.2, 33.5, 36.5, 38.7];

const daysWithCriticalAmount = dailyReadings.filter(day => {
    return day < 30
});

if(daysWithCriticalAmount) {
    console.log("The amount of water was critical");
} else {
    console.log("The amount of water was normal");
}

你注意到什么了吗? 最后的 if 条件检查 daysWithCriticalAmount 这实际上是一个空数组,因为没有一天的水少于 30。

令人惊讶的是,如果您正赶在截止日期之前并且只想快速实现一个过滤器方法,那么这种错误就经常发生。 这段代码的问题在于,尤其是 JavaScript(是的,JavaScript 很奇怪)在很多方面都是一种不一致的语言。 有时事物的“真实性”就是其中之一。

正如您可能知道在 JavaScript [] == true 中返回 false 并且您可能认为上面的代码是正确的。

不幸的是,在 if 条件下,[] 的计算结果为真! 换句话说,永远不会执行 else 块。

解决这个问题非常简单,因为您只需检查结果数组的长度是否大于或等于 1。

3. reduce()

与本文中的所有其他函数相比,reduce() 正在争夺“令人困惑、怪异和复杂的 JavaScript 函数”的第一名。 尽管此功能非常重要并且在许多情况下会产生优雅的代码,但许多 JavaScript 开发人员都避免使用它。 他们更喜欢在没有 reduce() 帮助的情况下编写代码。

原因之一是 reduce() 的复杂性。 很难理解这个函数的概念和执行。 此外,如果你阅读它的描述,你必须重新阅读它几次,而且,如果你读错了,你会怀疑自己(发生在我身上,直到我看到它在行动)。

reduce() 函数用于将给定数组减少(很明显不是吗?)为单个值。 这可以是数字、字符串、函数、对象或其他任何东西。

如果你想使用 reduce() 函数来减少数组,你需要通过提供一个函数来提供所需的逻辑。 通常,此函数将称为将第一个参数转换为 reduce() 的 reducer 函数。 此外,它还包含第二个参数,它是一个起始值,可以是数字、字符串等。函数本身如下所示:

array.reduce(reducerFunction, startValue)

startValue:传递给 reduce() 函数的 startValue 是您要使用 reducerFunction 处理的计算的起始值(显而易见...)。 例如,如果要执行加法,则可以从 0 开始;如果要执行乘法,则应使用值 1。

reducerFunction:如前所述,reducer 函数用于将数组转换为单个值。 它有两个参数:一个累加器和一个存储当前值的变量。

累加器只是一个奇特的名称,描述了包含计算结果的变量(就像使用 total 来求和数组中的所有项)。 在 reducer 函数中,累加器将被初始设置为起始值,然后计算将逐步遍历数组,同时每一步的结果保存在累加器中。

reducer 函数的第二个参数是 currentValue,它将包含数组中特定步骤中给定位置的值。 例如,在步骤 2 中执行 reducer 函数时,变量 currentValue 将包含输入数组中的第二个值。

有了所有这些信息,我们应该看看下面的示例,它将在 reducer 函数中添加输入数组中的每个值:

const input = [1, 2, 3, 4];
const result = input.reduce((acc, currentValue) => acc + currentValue, 0);
console.log(result); // 10

在第一行中,我们定义了包含我们要添加的所有数字的输入数组。 下一行将包含 input.reduce() 调用,它将 acc 的起始值定义为 0,因为另外我们应该从 0 开始以不影响结果。 reducer 函数 body (acc, currentValue) => acc + currentValue 对当前值和存储在累加器中的值进行简单相加。

如果你用 for 循环做这个加法,它看起来像这样:

const input = [1, 2, 3, 4];
let result = 0;
for (let i = 0; i < input.length; i++) {
    result += input[i]
}
console.log(total)

如您所见,简单的 for 循环示例要长得多,而且不如使用 reduce 优雅。

4. some()

假设您有一组对象,其中包含学生及其在考试中的分数。 现在,您想知道班上是否有学生的分数高于 90%,而不关心是否有一名或多名学生以超过 90% 的成绩通过了该考试。

如果您想在 JavaScript 中执行此操作,您可以使用循环和在找到得分大于 90% 的第一个人后设置为 true 的变量来解决问题:

const students = [{
    name: "Stud 1",
    score: 78,
}, {
    name: "Stud 2",
    score: 92
}, {
    name: "Stud 3",
    score: 90
}]

let over90 = false;

for(let i = 0; i < students.length; i++) {
    if(students[i].score > 90) {
        over90 = true;
        break;
    }
}

if(over90) {
    console.log("There are students with exceptional score!")
} else {
    console.log("Unfortunately, nothing is exceptional")
}

对我来说,这段代码看起来非常“丑陋”、“冗长”或“可怕”!

可以使用前面描述的 map() 函数对其进行优化,但解决方案仍然有点笨拙。

幸运的是,JavaScript 有一个名为 some() 的相当简洁的函数,它在核心语言中可用,可以处理数组,并返回一个布尔值。 在提供匿名函数的同时,它将过滤输入数组以优雅地解决问题:

const students = [{
    name: "Stud 1",
    score: 78,
}, {
    name: "Stud 2",
    score: 92
}, {
    name: "Stud 3",
    score: 90
}]

if(students.some(student => {
    return student.score > 90
})) {
    console.log("There are students with exceptional score!")
} else {
    console.log("Unfortunately, nothing is exceptional")
}

您可以看到它获得相同的输入并以更优雅的方式产生相同的结果。 此外,代码量减少了,可读性也比以前高了很多。

5. every()

JavaScript 核心语言中已经存在的另一个函数是 every()。 此函数将返回一个布尔值(如 some()),但将测试输入数组中的所有项目。 为此,您必须(再次)提供一个匿名函数。 例如,我们将通过考试成绩达到 70 分或以上来测试是否每个学生都通过了考试:

const students = [{
    name: "Stud 1",
    score: 78,
}, {
    name: "Stud 2",
    score: 92
}, {
    name: "Stud 3",
    score: 90
}]

if(students.every(student => {
    return student.score > 70
})) {
    console.log("All students passed the exam!")
} else {
    console.log("Unfortunately, not all students did well")
}

与 some() 一样,此函数创建简洁的优雅、可读和可维护的代码。

6. includes()

通常,如果我想检查一个数组是否存在子字符串,我会使用 indexOf()。 不幸的是,我必须查阅文档才能了解它们的返回值。

幸运的是,JavaScript 中有一个很好的替代方法可以用来实现这一点:includes()。 用法非常简单,并且区分大小写(我猜你无论如何都希望如此)。 有关示例,请参见以下代码片段:

const numbers = [6, 5, 13, 26, 48, 1];
console.log(numbers.includes(5)); // true

const name = "Paul Knulst";
console.log(name.includes('paul')); // false, because first letter is in small
console.log(name.includes('Paul')); // true, as expected

但是,includes 只能比较简单的值而不能比较对象:

const user = {a: 6, b: 5, c: 26};
console.log(user.includes('b')); // does not work because objects does not have an "includes" method

7. shift()

如果你想删除数组的第一个元素 shift() 是你应该使用的方法,因为它易于记忆且直观。 请注意,您也可以使用 splice(稍后查看)来执行此操作,但 shift() 更容易:

const input = [1, 2, 3, 4];
const first = input.shift();
console.log(input); // gives: Array [2, 3, 4]
console.log(first); // gives: 1

正如您在此处看到的那样,shift 改变了调用它的数组并返回删除的元素。

注意:shift 效率极低,如果您正在使用大型数组,则应避免使用。 在大型数组上过多调用 shift() 可能会破坏您的应用程序!

8. unshift()

与删除一个元素的 shift() 相比,此函数用于在数组的开头添加一个新元素:

const input = [1, 2, 3, 4];
input.unshift(0);
console.log(input); // expected output: Array [0, 1, 2, 3, 4]

注意:与 shift 一样,unshift 效率极低,如果您正在处理大型数组,则应避免使用。 在大型数组上调用太多 unshift() 可能会破坏您的应用程序!

9. slice()

在 JavaScript 中存在一个称为切片的概念,它是一种通过提供起始索引和结束索引来创建包含原始字符串的一部分的新字符串的函数。 现在,借助 indexOf 函数,您可以对输入字符串进行切片以检索搜索到的子字符串:

const input = "This is a cool article about mandatory JavaScript functions that every developer shoud know";
const start = input.indexOf("cool");
const end = input.indexOf("that");
const headline = input.slice(start, end);
console.log(headline); // "cool article about mandatory JavaScript functions"

请注意,开始索引包含在结果数组中,但结束索引不包含。 此外,您还可以看到“functions”和“that”之间的空格也没有被分割。

此外,切片也可以用于数组:

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2)); // ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4)); // Array ["camel", "duck"]

10. splice()

splice() 听起来像 slice() 并且可以与它进行比较,因为这两个函数都从原始数组或字符串创建新的数组或字符串。 主要的小但非常重要的区别是 splice() 删除、更改或添加元素但修改原始数组。 如果您不完全理解深拷贝和引用在 JavaScript 中的工作原理,原始数组的这种“解构”可能会导致巨大的问题!

以下示例将展示如何使用 splice() :

const months = ['Jan', 'March', 'April', 'June'];
const feb = months.splice(1, 0, 'Feb'); // inserts at index 1
console.log(months); // ["Jan", "Feb", "March", "April", "June"]
console.log(feb); // []

const may = months.splice(4, 1, 'May'); // replaces 1 element at index 4
console.log(months); // ["Jan", "Feb", "March", "April", "May"]
console.log(may); // ["June"]

你可以在这里看到 splice() 操作原始数组。 如果您删除一个项目,它也会返回删除的条目,但如果您添加一个条目,则返回数组将为空。

11. fill()

最后一个 JavaScript 函数是 fill(),用于将多个项目更改为单个值,甚至将整个数组重置为其初始值。 如果你需要这个 fill() 可以帮助你避免循环来重置数组的值。 此外,该函数可用于用给定值替换数组中的部分或全部条目。

您可以在以下示例中看到它是如何工作的:

const input = [1, 2, 3, 4, 5, 6];
console.log(input.fill(0, 2, 4)); // [1, 2, 0, 0, 0, 0]
console.log(input.fill(5, 1)); // [1, 5, 5, 5, 5, 5]
console.log(input.fill(6)); // [6, 6, 6, 6, 6, 6]

结论

此列表包含大多数 JavaScript 开发人员在其职业生涯中遇到和使用的函数。 虽然很长,但绝不是完整的,因为 JavaScript 中还有许多次要但非常有用的函数:reverse()、sort()、find()、flat()、entries()。 我建议您阅读这些函数,因为您随时都会在 JavaScript 项目中使用它们。

此外,只要有可能,你都应该探索核心语言或著名的实用程序库,如 lodash,以加深你的 JavaScript 知识。 它将带来巨大的生产力,您将学会创建更清晰、紧凑、可读、可维护和可用的代码!

展开阅读全文

页面更新:2024-05-31

标签:函数   代码   可能会   水量   数组   示例   字符串   元素   原始   核心   语言   质量

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top