zoukankan      html  css  js  c++  java
  • 第19条:熟练掌握高阶函数

    Higher-order functions used to be a shibboleth of the monks of func-
    tional programming, an esoteric term for what seemed like an
    advanced programming technique. Nothing could be further from the
    truth. Exploiting the concise elegance of functions can often lead to
    simpler and more succinct code. Over the years, scripting languages
    have adopted these techniques and in the process taken much of the
    mystery out of some of the best idioms of functional programming.
    Higher-order functions are nothing more than functions that take
    other functions as arguments or return functions as their result.
    Taking a function as an argument (often referred to as a callback
    function because it is “called back” by the higher-order function) is a
    particularly powerful and expressive idiom, and one that JavaScript
    programs use heavily.
    Consider the standard sort method on arrays. In order to work on all
    possible arrays, the sort method relies on the caller to determine how
    to compare any two elements in an array:

    function compareNumbers(x, y) {
    if (x < y) {
    return -1;
    }
    if (x > y) {
    return 1;
    }
    return 0;
    }
    [3, 1, 4, 1, 5, 9].sort(compareNumbers); // [1, 1, 3, 4, 5, 9]

    The standard library could have required the caller to pass in an
    object with a compare method, but since only one method is required,
    taking a function directly is simpler and more concise. In fact, the
    above example can be simplified further with an anonymous function:

    [3, 1, 4, 1, 5, 9].sort(function(x, y) {
    if (x < y) {
    return -1;
    }
    if (x > y) {
    return 1;
    }
    return 0;
    }); // [1, 1, 3, 4, 5, 9]

    Learning to use higher-order functions can often simplify your code
    and eliminate tedious boilerplate. Many common operations on
    arrays have lovely higher-order abstractions that are worth familiar-
    izing yourself with. Consider the simple act of transforming an array
    of strings. With a loop, we’d write:

    var names = ["Fred", "Wilma", "Pebbles"];
    var upper = [];
    for (var i = 0, n = names.length; i < n; i++) {
    upper[i] = names[i].toUpperCase();
    }
    upper; // ["FRED", "WILMA", "PEBBLES"]

    With the handy map method of arrays (introduced in ES5), we
    can completely eliminate the loop details, implementing just the
    element-by-element transformation with a local function:

    var names = ["Fred", "Wilma", "Pebbles"];
    var upper = names.map(function(name) {
    return name.toUpperCase();
    });
    upper; // ["FRED", "WILMA", "PEBBLES"]

    Once you get the hang of using higher-order functions, you can
    start identifying opportunities to write your own. The telltale sign
    of a higher-order abstraction waiting to happen is duplicate or sim-
    ilar code. For example, imagine we found one part of a program con-
    structing a string with the letters of the alphabet:

    var aIndex = "a".charCodeAt(0); // 97
    var alphabet = "";
    for (var i = 0; i < 26; i++) {
    alphabet += String.fromCharCode(aIndex + i);
    }
    alphabet; // "abcdefghijklmnopqrstuvwxyz"

    Meanwhile, another part of the program generates a string contain-
    ing numeric digits:

    var digits = "";
    for (var i = 0; i < 10; i++) {
    digits += i;
    }
    digits; // "0123456789"

    Still elsewhere, the program creates a random string of characters:

    var random = "";
    for (var i = 0; i < 8; i++) {
    random += String.fromCharCode(Math.floor(Math.random() * 26)
    + aIndex);
    }
    random; // "bdwvfrtp" (different result each time)

    Each example creates a different string, but they all share common
    logic. Each loop creates a string by concatenating the results of some
    computation to create each individual segment. We can extract the
    common parts and move them into a single utility function:

    function buildString(n, callback) {
    var result = "";
    for (var i = 0; i < n; i++) {
    result += callback(i);
    }
    return result;
    }

    Notice how the implementation of buildString contains all the com-
    mon parts of each loop, but uses a parameter in place of the parts
    that vary: The number of loop iterations becomes the variable n ,
    and the construction of each string segment becomes a call to the
    callback function. We can now simplify each of the three examples to
    use buildString :

    var alphabet = buildString(26, function(i) {
    return String.fromCharCode(aIndex + i);
    });
    alphabet; // "abcdefghijklmnopqrstuvwxyz"
    var digits = buildString(10, function(i) { return i; });
    digits; // "0123456789"
    var random = buildString(8, function() {
    return String.fromCharCode(Math.floor(Math.random() * 26)
    + aIndex);
    });
    random; // "ltvisfjr" (different result each time)

    There are many benefits to creating higher-order abstractions. If
    there are tricky parts of the implementation, such as getting the loop
    boundary conditions right, they are localized to the implementation
    of the higher-order function. This allows you to fix any bugs in the
    logic just once, instead of having to hunt for every instance of the cod-
    ing pattern spread throughout your program. If you find you need to
    optimize the efficiency of the operation, you again only have one place
    where you need to change anything. Finally, giving a clear name such
    as buildString to the abstraction makes it clearer to someone reading
    the code what the code does, without having to decode the details of
    the implementation.
    Learning to reach for a higher-order function when you find your-
    self repeatedly writing the same patterns leads to more concise code,
    higher productivity, and improved readability. Keeping an eye out for
    common patterns and moving them into higher-order utility func-
    tions is an important habit to develop.
    Things to Remember
    ✦ Higher-order functions are functions that take other functions as
    arguments or return functions as their result.
    ✦ Familiarize yourself with higher-order functions in existing
    libraries.
    ✦ Learn to detect common coding patterns that can be replaced by
    higher-order functions.

     文章来源于:Effective+Javascript编写高质量JavaScript代码的68个有效方法 英文版

    progress every day !
  • 相关阅读:
    IBM Lotus网站荟萃
    Lotus 深入浅出系列——前言(二)IBM Lotus开发人员的几个境界
    在IIS上配置和测试Perl脚本
    网站推广
    iTOP开发板MiniLinuxC程序调用shell命令
    iTOP4412开发板_驱动_adc驱动升级和测试例程
    最近想入手树莓派3来学习编程同学没有选择4412开发板吗?
    iTOP4412开发板串口转接小板的使用文档
    学习嵌入式4412开发板手把手配套视频_2000人群组在线交流
    电子医疗设备创新研发应该用i.MX6Q开发板吗?为医疗设备提供解决方案
  • 原文地址:https://www.cnblogs.com/hghrpg/p/4594035.html
Copyright © 2011-2022 走看看