美文网首页让前端飞工作生活Web前端之路
读Javascript最佳实践(2)-使用默认参数和速记(sho

读Javascript最佳实践(2)-使用默认参数和速记(sho

作者: 全栈顾问 | 来源:发表于2019-07-29 10:43 被阅读8次

    一句话总结:强烈建议掌握!函数参数默认值和属性速记(shorthands)减少了重复代码,降低了无意的工作量,使代码更清晰。

    翻译自《javascript-best-practice》

    创建方法还意味着编写API —— 无论是为自己,团队中的其他开发人员,还是其他使用你项目的开发人员。根据功能的大小,复杂性和用途,你必须考虑默认设置和输入/输出的API。

    默认函数参数属性shorthands是ES6的两个便捷功能,可以帮助你编写API。

    ES6默认参数

    让我们快速了解我们的知识并再次查看语法。默认参数允许我们使用默认值初始化函数。当省略参数或者undefined时,参数设置为null。默认参数可以是从数字到另一个函数的任何内容。

    // Basic syntax
    function multiply (a, b = 2) {
      return a * b;
    }
    multiply(5); // 10
    
    // Default parameters are also available to later default parameters
    function foo (num = 1, multi = multiply(num)) {
      return [num, multi];
    }
    foo(); // [1, 2]
    foo(6); // [6, 12]
    

    一个现实世界的例子

    让我们来看一个基本功能,并演示默认参数如何加速你的开发并使代码更有条理。

    我们的示例方法叫做createElement()。它需要一些配置参数,并返回一个HTML元素。API看起来像这样:

    // We want a <p> element, with some text content and two classes attached.
    // Returns <p class="very-special-text super-big">Such unique text</p>
    createElement('p', {
      content: 'Such unique text',
      classNames: ['very-special-text', 'super-big']
    });
    
    // To make this method even more useful, it should always return a default
    // element when any argument is left out or none are passed at all.
    createElement(); // <div class="module-text default">Very default</div>
    

    这个实现没有太多逻辑,但由于它的默认值覆盖范围,代码可能会变得非常大。

    // Without default parameters it looks quite bloated and unnecessary large.
    function createElement (tag, config) {
      tag = tag || 'div';
      config = config || {};
    
      const element = document.createElement(tag);
      const content = config.content || 'Very default';
      const text = document.createTextNode(content);
      let classNames = config.classNames;
    
      if (classNames === undefined) {
        classNames = ['module-text', 'default'];
      }
    
      element.classList.add(...classNames);
      element.appendChild(text);
    
      return element;
    }
    

    到现在为止还挺好。这里发生了什么事?我们正在做以下事情:

    1. 如果tagconfig没有被传递,为我们的参数设置默认值
    2. 使用实际内容(和默认值)创建常量
    3. 检查是否classNames已定义,如果没有则指定默认数组
    4. 在返回之前创建和修改元素。

    现在让我们优化一下这个函数的写法:

    // Default all the things
    function createElement (tag = 'div', {
      content = 'Very default',
      classNames = ['module-text', 'special']
    } = {}) {
      const element = document.createElement(tag);
      const text = document.createTextNode(content);
    
      element.classList.add(...classNames);
      element.appendChild(text);
    
      return element;
    }
    

    我们没有触及函数的逻辑,但从函数体中删除了所有默认处理。该函数签名现在包含所有默认值。

    让我进一步解释一个可能有点令人困惑的部分:

    // What exactly happens here?
    function createElement ({
      content = 'Very default',
      classNames = ['module-text', 'special']
    } = {}) {
      // function body
    }
    

    我们不仅声明默认object参数,还声明默认对象属性。这使得默认配置看起来更加明显,而不是仅声明默认对象(例如config = {})以及稍后设置默认属性。你可能需要一些额外的时间来适应它,但最终它会改善你的工作流程。

    ES6属性速写(shorthand)

    如果函数需要接受大型配置对象作为参数,则代码可能会变得非常大。准备一些变量并将它们添加到这个对象是很常见的。属性简写是语法糖,使这一步骤更短,更易读:

    const a = 'foo', b = 42, c = function () {};
    
    // Previously we would use these constants like this.
    const alphabet = {
      a: a,
      b: b,
      c: c
    };
    
    // But with the new shorthand we can actually do this now,
    // which is equivalent to the above.
    const alphabet = { a, b, c };
    

    缩短API

    好的,回到另一个更常见的例子。以下函数获取一些数据,对其进行变异并调用另一个方法:

    function updateSomething (data = {}) {
      const target = data.target;
      const veryLongProperty = data.veryLongProperty;
      let willChange = data.willChange;
    
      if (willChange === 'unwantedValue') {
        willChange = 'wayBetter';
      }
    
      // Do more.
    
      useDataSomewhereElse({
        target: target,
        property: veryLongProperty,
        willChange: willChange,
        // .. more
      });
    }
    

    通常我们将变量命名为和对象属性名称相同的名称。使用属性简写,结合解构,我们实际上可以缩短我们的代码:

    function updateSomething (data = {}) {
      // 从data对象中解构出常量,而且重新命名veryLongProperty
      const { target, veryLongProperty: property } = data;
      let { willChange } = data;
    
      if (willChange === 'unwantedValue') {
        willChange = 'wayBetter';
      }
    
      // Do more.
    
      useDataSomewhereElse({ target, property, willChange });
    }
    

    同样,这可能需要一段时间才能习惯。最后,它是JavaScript中的一个新功能,它帮助我更快地编写代码并使用更清晰的函数体。

    但等等,还有更多!属性简写也可以应用于对象内的方法定义:

    // 声明方法时需要使用function关键字
    const module = {
      foo: 42,
      bar: function (value) {
        // do something
      }
    };
    
    // 缩短bar方法的声明
    const module = {
      foo: 42,
      bar (value) {
        // do something
      }
    };
    

    结论

    默认参数和属性简写是使函数更有条理的好方法,在某些情况下甚至更短。总的来说,默认函数参数帮助我更多地关注方法的实际目的,而不会分散大量的默认准备和if语句。

    属性shorthands确实更像是一种装饰性功能,但我发现自己的工作效率更高,并且花费更少的时间来编写所有变量,配置对象和function关键字。

    相关文章

      网友评论

        本文标题:读Javascript最佳实践(2)-使用默认参数和速记(sho

        本文链接:https://www.haomeiwen.com/subject/vodwcctx.html