# 函数

  • 7.2 把立即执行函数包裹在圆括号里。 eslint: wrap-iife (opens new window)

    Why? immediately invoked function expression = IIFE Why? 一个立即调用的函数表达式是一个单元 - 把它和他的调用者(圆括号)包裹起来,在括号中可以清晰的地表达这些。 Why? 注意:在模块化世界里,你几乎用不着 IIFE

    // immediately-invoked function expression (IIFE)
    (function () {
      console.log('Welcome to the Internet. Please follow me.');
    }());
    
  • 7.3 不要在非函数块(if、while等等)内声明函数。把这个函数分配给一个变量。浏览器会允许你这样做,但浏览器解析方式不同,这是一个坏消息。【详见no-loop-func】 eslint: no-loop-func (opens new window)

  • 7.4 Note: 在ECMA-262中 [块 block] 的定义是: 一系列的语句; 但是函数声明不是一个语句。 函数表达式是一个语句。

    // bad
    if (currentUser) {
      function test() {
        console.log('Nope.');
      }
    }
    
    // good
    let test;
    if (currentUser) {
      test = () => {
        console.log('Yup.');
      };
    }
    
  • 7.5 不要用arguments命名参数。他的优先级高于每个函数作用域自带的 arguments 对象, 这会导致函数自带的 arguments 值被覆盖

    // bad
    function foo(name, options, arguments) {
      // ...
    }
    
    // good
    function foo(name, options, args) {
      // ...
    }
    
  • 7.6 不要使用arguments,用rest语法...代替。 eslint: prefer-rest-params (opens new window)

    Why? ...明确你想用那个参数。而且rest参数是真数组,而不是类似数组的arguments

    // bad
    function concatenateAll() {
      const args = Array.prototype.slice.call(arguments);
      return args.join('');
    }
    
    // good
    function concatenateAll(...args) {
      return args.join('');
    }
    
  • 7.7 用默认参数语法而不是在函数里对参数重新赋值。

    // really bad
    function handleThings(opts) {
      // 不, 我们不该改arguments
      // 第二: 如果 opts 的值为 false, 它会被赋值为 {}
      // 虽然你想这么写, 但是这个会带来一些细微的bug
      opts = opts || {};
      // ...
    }
    
    // still bad
    function handleThings(opts) {
      if (opts === void 0) {
        opts = {};
      }
      // ...
    }
    
    // good
    function handleThings(opts = {}) {
      // ...
    }
    
  • 7.8 默认参数避免副作用

    Why? 他会令人迷惑不解, 比如下面这个, a到底等于几, 这个需要想一下。

    let b = 1;
    // bad
    function count(a = b++) {
      console.log(a);
    }
    count();  // 1
    count();  // 2
    count(3); // 3
    count();  // 3
    
  • 7.9 把默认参数赋值放在最后

    // bad
    function handleThings(opts = {}, name) {
      // ...
    }
    
    // good
    function handleThings(name, opts = {}) {
      // ...
    }
    
  • 7.10 不要用函数构造器创建函数。 eslint: no-new-func (opens new window)

    Why? 以这种方式创建函数将类似于字符串 eval(),这会打开漏洞。

    // bad
    const add = new Function('a', 'b', 'return a + b');
    
    // still bad
    const subtract = Function('a', 'b', 'return a - b');
    
  • 7.11 函数签名部分要有空格。eslint: space-before-function-paren (opens new window) space-before-blocks (opens new window)

    Why? 统一性好,而且在你添加/删除一个名字的时候不需要添加/删除空格

    // bad
    const f = function(){};
    const g = function (){};
    const h = function() {};
    
    // good
    const x = function () {};
    const y = function a() {};
    
  • 7.12spread操作符...去调用多变的函数更好。 eslint: prefer-spread (opens new window)

    Why? 这样更清晰,你不必提供上下文,而且你不能轻易地用apply来组成new

    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    
    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);
    
    // bad
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
    
    // good
    new Date(...[2016, 8, 5]);
    

回到顶部