前端编码规范(3)JavaScript 开发规范(2)

(function(log){ ‘use strict'; // All variables used in the closure will be hoisted to the top of the function var a, i, b, f; // All functions in the closure will be hoisted to the top function x() { log(‘Mr. X!'); } a = 10; for(i = 0; i < a; i++) { b = i * i; log(b); } if(a === 10) { // Function assignments will only result in hoisted variables but the function body will not be hoisted // Only by using a real function declaration the whole function will be hoisted with its body f = function() { log(a); }; f(); } x(); }(window.console.log));

根据以上提升过程,你是否可理解以下代码?

有效代码

(function(log){ ‘use strict'; var a = 10; i = 5; x(); for(var i; i < a; i++) { log(b); var b = i * i; } if(a === 10) { f = function() { log(a); }; f(); var f; } function x() { log(‘Mr. X!'); } }(window.console.log));

正如你所看到的这段令人充满困惑与误解的代码导致了出人意料的结果。只有良好的声明习惯,也就是下一章节我们要提到的声明规则,才能尽可能的避免这类错误风险。

提升声明

为避免上一章节所述的变量和方法定义被自动提升造成误解,把风险降到最低,我们应该手动地显示地去声明变量与方法。也就是说,所有的变量以及方法,应当定义在 function 内的首行。
只用一个 var 关键字声明,多个变量用逗号隔开。

不推荐 (function(log){ ‘use strict'; var a = 10; var b = 10; for(var i = 0; i < 10; i++) { var c = a * b * i; } function f() { } var d = 100; var x = function() { return d * d; }; log(x()); }(window.console.log)); 推荐 (function(log){ ‘use strict'; var a = 10, b = 10, i, c, d, x; function f() { } for(i = 0; i < 10; i++) { c = a * b * i; } d = 100; x = function() { return d * d; }; log(x()); }(window.console.log));

把赋值尽量写在变量申明中。

不推荐 var a, b, c; a = 10; b = 10; c = 100; 推荐 var a = 10, b = 10, c = 100;

总是使用带类型判断的比较判断

总是使用 === 精确的比较操作符,避免在判断的过程中,由 JavaScript 的强制类型转换所造成的困扰。
如果你使用 === 操作符,那比较的双方必须是同一类型为前提的条件下才会有效。
如果你想了解更多关于强制类型转换的信息,你可以读一读 Dmitry Soshnikov 的这篇文章。
在只使用 == 的情况下,JavaScript 所带来的强制类型转换使得判断结果跟踪变得复杂,下面的例子可以看出这样的结果有多怪了:

(function(log){ ‘use strict'; log(‘0' == 0); // true log(” == false); // true log(‘1' == true); // true log(null == undefined); // true var x = { valueOf: function() { return ‘X'; } }; log(x == ‘X'); }(window.console.log));

明智地使用真假判断

当我们在一个 if 条件语句中使用变量或表达式时,会做真假判断。if(a == true) 是不同于 if(a) 的。后者的判断比较特殊,我们称其为真假判断。这种判断会通过特殊的操作将其转换为 true 或 false,下列表达式统统返回 false:false, 0, undefined, null, NaN, ”(空字符串).

这种真假判断在我们只求结果而不关心过程的情况下,非常的有帮助。

以下示例展示了真假判断是如何工作的:

(function(log){ ‘use strict'; function logTruthyFalsy(expr) { if(expr) { log(‘truthy'); } else { log(‘falsy'); } } logTruthyFalsy(true); // truthy logTruthyFalsy(1); // truthy logTruthyFalsy({}); // truthy logTruthyFalsy([]); // truthy logTruthyFalsy(‘0'); // truthy logTruthyFalsy(false); // falsy logTruthyFalsy(0); // falsy logTruthyFalsy(undefined); // falsy logTruthyFalsy(null); // falsy logTruthyFalsy(NaN); // falsy logTruthyFalsy(”); // falsy }(window.console.log));

变量赋值时的逻辑操作

逻辑操作符 || 和 && 也可被用来返回布尔值。如果操作对象为非布尔对象,那每个表达式将会被自左向右地做真假判断。基于此操作,最终总有一个表达式被返回回来。这在变量赋值时,是可以用来简化你的代码的。

不推荐

if(!x) { if(!y) { x = 1; } else { x = y; } }

推荐

x = x || y || 1;

这一小技巧经常用来给方法设定默认的参数。

(function(log){ 'use strict'; function multiply(a, b) { a = a || 1; b = b || 1; log('Result ' + a * b); } multiply(); // Result 1 multiply(10); // Result 10 multiply(3, NaN); // Result 3 multiply(9, 5); // Result 45 }(window.console.log));

分号

总是使用分号,因为隐式的代码嵌套会引发难以察觉的问题。当然我们更要从根本上来杜绝这些问题[1] 。以下几个示例展示了缺少分号的危害:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwdzys.html