23 个 JavaScript 最佳实践 - 最实用篇
1. 使用 ===
代替 ==
JavaScript 使用两种不同的相等运算符: ===
和 !==
是严格相等运算符,而 ==
和 !=
是非严格运算符。当二者相比较时始终使用严格相等被认为是最佳实践。
“如果两个操作数的类型和值相同,则 ===
产生真,而 !==
产生假。” ---- 来自JavaScript:好的部分
但是,在使用 ==
和 !=
时,你会发现在使用不同类型时会一些遇到问题。当您比较的值具有不同类型时,非严格运算符将尝试强制转换它们的值,您可能会得到意想不到的结果。
2. eval()
不好
对于当初不熟悉时,该 eval()
函数使我们能够访问 JavaScript 的编译器。本质上,我们可以通过将字符串传递给eval()
作为参数来执行字符串的结果。
这不仅会显着降低脚本的性能,而且还会带来巨大的安全风险,因为这样付给要执行的文本太高的权限。所以我们尽量躲开它!
3. 不要使用简写
从技术上讲,您可以省略大多数花括号和分号。大多数浏览器会正确解释以下内容:
if(someVariableExists)
x = false
但是,请考虑:
if(someVariableExists)
x = false
anotherFunctionCall();
}
有人可能认为上面的代码等价于:
if(someVariableExists) {
x = false;
anotherFunctionCall();
}
不幸的是,他错了。实际上,这意味着:
if(someVariableExists) {
x = false;
}
anotherFunctionCall();
您可能会注意到,上面缩进容易给人花括号的功能的假象。不用说,这是一种可怕的实践,应该不惜一切代价去避免。花括号应该被省略的唯一一次是单行的时候,即使这是一个备受争议的话题。
if(2 + 2 === 4) return 'nicely done';
要做到未雨绸缪
如果以后需要向此 if 语句添加更多命令,该怎么办呢?为此,您需要重写此代码块。底线--在省略时需谨慎行事。
4. 使用 JS Lint
JSLint
是由 Douglas Crockford
编写的调试器。简单的只需粘贴您的脚本进去,它就会快速扫描您代码中的任何明显问题和错误。
“JSLint
获取 JavaScript 源代码并对其进行扫描。如果发现问题,它会返回一条描述问题的消息以及源代码中的大致位置。问题不一定是语法错误,尽管通常是这样。JSLint
h还会查看一些编码风格和程序结构问题,它并不能证明您的程序是正确的。它只是提供了另一双眼睛来帮助发现问题。” - JSLint
文档
在部署脚本之前,请通过 JSLint
运行它,以确保您没有犯任何无意识的错误。
5. 将脚本放在页面底部
此技巧已在本系列的前一篇文章中推荐(后续更新)。由于它非常合适,我将粘贴信息。
cahtu
请记住——主要目标是让用户尽快加载页面。脚本加载并执行完成之前,浏览器不能继续渲染下面内容。因此,用户将不得不等待更长时间来注意到任何进展。
如果您的 JS
文件的唯一目的是添加功能(例如,按钮的单击事件),马上将脚本放在body
结束之前。这绝对是最佳实践。
建议
<p>And now you know my favorite kinds of corn. </p>
<script type="text/javascript" src="path/to/file.js"></script>
<script type="text/javascript" src="path/to/anotherFile.js"></script>
</body>
</html>
6. 在 For 语句之外声明变量
在执行冗长的 for
语句时,要保持语句块的尽量简洁。例如:
糟糕的
or(var i = 0; i < someArray.length; i++) {
var container = document.getElementById('container');
container.innerHtml += 'my number: ' + i;
console.log(i);
}
请注意我们在每次迭代时需计算数组的长度,以及我们每次都要遍历 DOM
以查找“container”元素——可见效率极低!
建议
var container = document.getElementById('container');
for(var i = 0, len = someArray.length; i < len; i++) {
container.innerHtml += 'my number: ' + i;
console.log(i);
}
7. 构建字符串的最快方法
当您需要循环遍历数组或对象时,不要总是使用方便的for
语句。发挥创造力,为手头的工作找到最快的解决方案。
var arr = ['item 1', 'item 2', 'item 3', ...];
var list = '<ul><li>' + arr.join('</li><li>') + '</li></ul>';
我不是所谓的神人,但你只需要相信我(或自己测试)——这是迄今为止最快的方法!
无论抽象层后面发生了什么,使用像join()
的本机方法,通常比任何非本机替代方法快得多。—-来自 James Padolsey, james.padolsey.com
8. 使用模板文字
我们用双引号或单引号创建的字符串有很多限制。您可能想用模板文字替换一些字符串,以便更轻松地使用它们。模板文字是使用反引号字符 ``` 来创建的,它们具有许多优点。您可以将表达式放入其中或创建多行字符串。
let person = 'Monty';
let fruits = 'apples';
let activity = 'playing games';
let day = 'Monday';
var sentence = person + ' will be eating ' + fruits + ' and ' + activity + ' on ' + day + '.';
console.log(sentence);
// Output: Monty will be eating apples and playing games on Monday.
var sentence = `${person} will be eating ${fruits} and ${activity} on ${day}.`;
console.log(sentence);
// Output: Monty will be eating apples and playing games on Monday.
如您所见,我们不必像使用单引号或双引号创建的常规字符串文字那样不断地移入和移出文字模板。这减少了任何输入相关错误的机会,并帮助我们编写更清晰的代码。
减少全局变量
“只要把多个全局变量都整理在一个名称空间下,拟将显著降低与其他应用程序、组件或类库之间产生糟糕的相互影响的可能性。” —- Douglas Crockford
var name = 'Jeffrey';
var lastName = 'Way';
function doSomething() {...}
console.log(name); // Jeffrey -- or window.name
建议
var DudeNameSpace = {
name : 'Jeffrey',
lastName : 'Way',
doSomething : function() {...}
}
console.log(DudeNameSpace.name); // Jeffrey
注:这里只是简单命名为 DudeNameSpace
,实际当中要取更合理的名字。
10. 考虑使用 let 和 const
该 let
关键字允许我们创建在自己的区块内范围的局部变量。该 const
关键字允许我们创建其值但不能重新分配局部块范围变量。你应该在适当的场合考虑使用关键字 let
和 const
声明的变量。请记住,关键字 const
只能防止重新分配。它不会使变量不可变。
var person_name = "Adam";
let name_length = person_name.length;
const fav_website = "code.tutsplus.com";
if(person_name.length < 5) {
var person_name = "Andrew";
let name_length = person_name.length;
// Throws an error if commented out!
// fav_website = "webdesign.tutsplus.com";
console.log(`${person_name} has ${name_length} characters.`);
// Output: Andrew has 6 characters.
}
console.log(`${person_name} has ${name_length} characters.`);
// Output: Andrew has 4 characters.
在上面的例子中, 我们在块内修改变量person_name
后,变量的值 if
块也在外更新 。另一方面,name_length
是块范围的,因此它在块之外保留了其原始值。
11. 注释你的代码
乍一看似乎没有必要,但相信我,您最好尽可能地注释您的代码。当你几个月后回到项目时(这过程可能会发生什么),却发现你无法轻易记住你的思路。或者,如果您的一位同事需要修改您的代码怎么办?所以,始终注释代码的才是重要的。
// Cycle through array and echo out each name.
for(var i = 0, len = array.length; i < len; i++) {
console.log(array[i]);
}
12. 拥抱渐进式增强
确保在 JavaScript 被禁用的情况下能平稳退化。你可能会想,“我的大多数访客都启用了 JavaScript,所以我不会担心。” 然而,这是一个很大的错误。
您是否曾花点时间来查看你漂亮的页面在 JavaScript 被关闭是是什么样的?(下载 Web Developer
工具就可以很容易做到 )它有可能会完全破坏您的网站。根据经验,设计您的网站时假设 JavaScript 是被禁用的。然后,在此基础上,逐步增强您的网站!
13. 不要将字符串传递给 setInterval
或 setTimeOut
考虑以下代码:
setInterval(
"document.getElementById('container').innerHTML += 'My new number: ' + i", 3000
);
这段代码不仅效率低下,而且还以与eval
函数相同的方式运行。永远不要将字符串传递给setInterval
and setTimeOut
。而是像以下方式传递函数名称。
setInterval(someFunction, 3000);
14. 使用 {} 代替 new Object()
在 JavaScript 中有多种创建对象的方法。也许更传统的方法是使用 new
加构造函数,如下所示:
var o = new Object();
o.name = 'Jeffrey';
o.lastName = 'Way';
o.someFunction = function() {
console.log(this.name);
}
然而,这种方受到的诟病不及实际上多。作为代替,我建议您使用对象字面量方法。
更好的做法
var o = new Object();
o.name = 'Jeffrey';
o.lastName = 'Way';
o.someFunction = function() {
console.log(this.name);
}
请注意,如果您只是想创建一个空对象, {}
就可以。
var o = {};
“对象字面量使我们能够编写更具特色的代码,,而且相对简单的多。无需直接调用构造函数或维持传递给函数的参数的正确顺序等。” —-来自dyn-web.com
使用 [] 代替 new Array()
这同样适用于创建一个新数组。
例如:
var a = new Array();
a[0] = "Joe";
a[1] = 'Plumber';
更好的做法:
var a = ['Joe','Plumber'];
“JavaScript 程序中的一个常见错误是在需要数组时使用对象或在需要对象时使用数组。规则很简单:当属性名是连续整数时,您应该使用数组。否则,请使用对象。” — Douglas Crockford
使用扩展运算符
您是否曾经遇到过想要将数组的所有项目作为单独元素传递给其他函数的情况,或者想要将一个数组中的所有值插入到另一个数组中?展开运算符 ...
可允许我们做到这一点。下面是一个例子:
let people = ["adam", "monty", "andrew"]
let more_people = ["james", "jack", ...people, "sajal"]
console.log(more_people)
// Output: Array(6) [ "james", "jack", "adam", "monty", "andrew", "sajal" ]
17. for in
语句
当遍历对象属性时,您可能会发现您还会检索方法函数。为了解决这个问题,请始终将您的代码包裹在 if
语句中过滤(信息。
for(key in object) {
if(object.hasOwnProperty(key) {
...then do something...
}
}
这个技巧来自 JavaScript: The Good Parts,作者是 Douglas Crockford。
18. 阅读,阅读,阅读......
虽然我是 Web 开发博客的忠实粉丝(就像这个!),但在吃午饭或睡觉前,实在没有一本书更合适了。坚持在床头柜上放一本 Web 开发书。以下是我最喜欢的一些 JavaScript。
《 Object-Oriented JavaScript 》 《 JavaScript: The Good Parts 》 《 Learning JavaScript 》
要多去阅读它们。直到现在我还会依旧反复阅读!
自执行函数 这不是调用函数,而是在页面加载或调用父函数时使函数自动运行,这非常简单。只需将您的函数用圆括号包裹起来,然后附加一个额外的设置,它本质上就是调用该函数。
(function doSomething() {
return {
name: 'jeff',
lastName: 'way'
};
})();
20. 原生代码永远比库快
JavaScript 库,例如 jQuery
和 lodash
,可以在编码时为您节省大量时间,尤其是 AJAX
操作。话虽如此,请记住,库永远不会比原生 JavaScript 代码更快(假设您代码正确)。
jQuery
的 each()
方法非常棒的循环,但使用原生 for
语句总是会快一些。
21.使用解构快速分配变量值
我们已经在本文前面了解了 JavaScript 中的展开运算符。解构有点类似,因为它也解包存储在数组中的值。不同之处在于我们可以将这些未打包的值分配给唯一变量。
语法类似于使用[]
速记来创建数组 。但是,这次括号位于赋值运算符的左侧。下面是一个例子:
let [person, fruit, , day] = ['Monty', 'apple', 'reading', 'tomorrow'];
var sentence = `${person} will eat an ${fruit} ${day}.`;
console.log(sentence);
// Output: Monty will eat an apple tomorrow.
您是否注意到我们只是将第三个数组元素分配给任何变量而不用通过传递变量名?这使我们可以避免对不需要的值进行变量赋值。
22. 迭代器和 for
...... of
循环
JavaScript 中的迭代器是实现 next()
方法以返回一个对象的对象,该对象按顺序存储下一个值, true
或 false
取决于是否还有剩余值。这意味着如果您实现迭代器协议,您可以创建自己的迭代器对象。
JavaScript 的也有一些内置的迭代器像String
, Array
和 Map
等。您可以使用for
... of
循环来遍历它们。与常规for
循环相比,这将更简洁且不易出错 。
let people = ["Andrew", "Adam", "James", "Jack"];
let people_count = people.length;
for(let i = 0; i < people_count; i++) {
console.log(people[i]);
}
/*
Andrew
Adam
James
Jack
*/
for(person of people) {
console.log(person);
}
/*
Andrew
Adam
James
Jack
*/
使用 for
...of
循环,我们不必跟踪数组的总长度或当前索引。这可以在创建嵌套循环时降低代码复杂性。
23. async
和 await
您可以使用 async
关键字来创建始终显式或隐式返回Promise的异步函数。您创建的异步函数可以await 通过停止执行直到解决返回的Promise来利用 关键字。async 函数外的代码 将继续正常执行。
在上面的示例中, "Hello Andrew" 两秒后记录,而所有其他 hello 立即记录。对delayed_hello() 函数的调用会 "Hello Adam" 立即记录 ,但要等待Promise解析才能记录 "Hello Andrew"。
就是这样,伙计们 所以你有它; JavaScript 初学者的 23个基本技巧。谢谢阅读
写在最后:
如果你感觉写得不错,帮我点个[ 在看
、赞
、关注
]吧让我们一起成为前端架构师! 关注公众号:全栈修炼,第一时间了解国内外前端前沿技术!