# 函数
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.12 用
spread
操作符...
去调用多变的函数更好。 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]);