最近公司热火朝天的学习reactjs,引入的最大的一个问题是,怎么写js code。好吧,大牛找了一个JavaScript Style Guide,是Airbnb的规范,英文的,导致对于其中的含义有时候拿不准。贴出来跟大家一起学习一下。
7 Functions 函数
-
7.1 Use function declarations instead of function expressions. jscs: requireFunctionDeclarations
使用函数定义代替函数表达式。Why? Function declarations are named, so they're easier to identify in call stacks. Also, the whole body of a function declaration is hoisted, whereas only the reference of a function expression is hoisted. This rule makes it possible to always use Arrow Functions in place of function expressions.
为什么?函数定义是有名字的,所以他们可以更容易的在调用栈中被识别出来。同样,方法定义的整个方法体被提前到最前面,而函数表达式只有对方法的引用会被提到最前。这条规则(7.1使用函数定义代替函数表达式)让总是使用箭头函数替换函数表达式变得具有可行性。(最后一句好难翻译。。。)
// bad const foo = function () { }; // good function foo() { }
*自己的理解:当你使用函数表达式的时候,是为了将来在某个地方重用这个函数。而箭头函数在形式上更像函数定义,却可以像变量一样当成参数传递。
*结合Hoist:当你使用函数表达式的时候,会有一段代码区间有产生错误的可能当没有Hoist的时候,我们必须在函数的定义之后才能调用。
//eg.
abc(); // throw reference error.
function abc() {};
abc(); // ok.
有了Hoist之后,我们就可以这样写。
//eg.
abc(); //work
function abc() {};
但是,如果我们用函数表达式:
eg. 1
abc(); // throw type error.
var abc = function () {};
eg. 2
abc(); // throw reference error.
const abc = function () {};//only this will work var abc = function () {}; abc();
写的麻烦一点,也更现实一点:
//untested
$('btn').click(handleClick); // ok.
function handleClick() {};$('btn').click(handleClick); // throw type error var handleClick = function () {}; $('btn').click(handleClick); // throw reference error var handleClick = function () {};
-
7.2 Immediately invoked function expressions: eslint: wrap-iife jscs: requireParenthesesAroundIIFE
IIFE:必须用小括号包围。Why? An immediately invoked function expression is a single unit - wrapping both it, and its invocation parens, in parens, cleanly expresses this. Note that in a world with modules everywhere, you almost never need an IIFE.
为什么?一个IIFE是一个完整的单位——包括它的定义和它的调用括号。把IIFE写在括号里,可以清楚的表达这个意思。注意,在一个到处都是在modules的世界里,你几乎用不到IIFE。
// immediately-invoked function expression (IIFE) (function () { console.log('Welcome to the Internet. Please follow me.'); }());
*IIFE是有历史原因的,javascript是function scope,为了避免无意中修改到其他变量(var的副作用),所以出现了IIFE——将自己的代码封装到一个匿名的函数里,并且定义之后立即执行。参考链接:JavaScript-Scoping-and-Hoisting
-
7.3 Never declare a function in a non-function block (if, while, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears. eslint: no-loop-func
绝对不要在一个非函数语句块里定义一个函数(例如,if/while)。用把函数赋给一个变量代替。浏览器允许你这么做,但是它们实现起来却不一样,这是一个很糟糕的记忆。
-
7.4 Note: ECMA-262 defines a block as a list of statements. A function declaration is not a statement. Read ECMA-262's note on this issue.
注意,ECMA-262定义了“一个语句块是一组语句”。函数定义不是语句。读ECMA-262的Note关注这个问题。
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}// good let test; if (currentUser) { test = () => { console.log('Yup.'); }; }
-
7.5 Never name a parameter arguments. This will take precedence over the arguments object that is given to every function scope.
不要把一个参数命名成arguments。这会覆盖每个函数都有的arguments。
// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }
*函数默认会有一个叫arguments的参数,来代表所有的参数。
x = findMax(1, 123, 500, 115, 44, 88); function findMax() { var i; var max = -Infinity; for (i = 0; i < arguments.length; i++) { if (arguments[i] > max) { max = arguments[i]; } } return max; }
-
7.6 Never use arguments, opt to use rest syntax ... instead. prefer-rest-params
永远不要用arguments,用rest语法...
代替。
_Why? ... is explicit about which arguments you want pulled. Plus, rest arguments are a real Array, and not merely Array-like like arguments.
为什么?...
能明确的标示哪一个参数你想展开。另外,rest参数是一个真实的数组,而不是像arguments那样,只是一个类似数组的变量。_
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
- 7.7 Use default parameter syntax rather than mutating function arguments.
用默认参数的语法,而不是修改函数的参数。
// really bad
function handleThings(opts) {
// No! We shouldn't mutate function arguments.
// Double bad: if opts is falsy it'll be set to an object which may
// be what you want but it can introduce subtle bugs.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
if (opts === void 0) {
opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
// ...
}
- 7.8 Avoid side effects with default parameters.
避免在默认参数中的副作用。不要在默认参数中修改外部的变量 参考
Why? They are confusing to reason about.
为什么?因为会让你迷惑为什么会这样。
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
- 7.9 Always put default parameters last.
总是把默认参数放到最后。
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
- 7.10 Never use the Function constructor to create a new function.
永远不要用函数构建器去创建一个新的函数。
Why? Creating a function in this way evaluates a string similarly to eval(), which opens vulnerabilities.
为什么?用这种方法去创建一个函数就像用 eval()
,非常容易被攻击。
- 7.11 Spacing in a function signature.
在函数签名中保留空格。
Why? Consistency is good, and you shouldn’t have to add or remove a space when adding or removing a name.
为什么,因为这样统一性很好。并且你在添加或删除名字的时候去添加、删除空格。
// bad
const f = function(){};
const g = function (){};
const h = function() {};
// good
const x = function () {};
const y = function a() {};
- 7.12 Never mutate parameters. eslint: no-param-reassign
永远不要修改参数。
Why? Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller.
为什么?操作参数里传进来的对象能导致调用者中不想要的副作用变化。
// bad
function f1(obj) {
obj.key = 1;
};
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
};
- 7.13 Never reassign parameters. eslint: no-param-reassign
永远不要重新给参数赋值。
Why? Reassigning parameters can lead to unexpected behavior, especially when accessing the arguments object. It can also cause optimization issues, especially in V8.
为什么?重新给参数赋值能导致不可预期的行为,特别是访问arguments对象。这么做同样能引起优化问题,特别是在V8引擎中。
// bad
function f1(a) {
a = 1;
}
function f2(a) {
if (!a) { a = 1; }
}
// good
function f3(a) {
const b = a || 1;
}
function f4(a = 1) {
}
网友评论