为了保证可读性, 本文采用意译而非直译. 另外, 本文版权归原作者所有, 翻译仅用于学习.
我决定为初学者写一篇博客来介绍一些常见编程技巧, 这些技巧可以帮助你写出更加规范, 容易维护的代码.
1. 常量
这个问题哦不仅仅是写 JavaScript 的开发者们会遇到, 在所有的开发语言中都要避免. 我们来看一个例子:
- $elem.on('keydown', function(e) {
- if (e.keyCode == 27) {
- //...
- }
- });
27 到底代表什么? 如果你经常编程, 很容易知道这个数字代表 ESC 键. 但是对大多数开发者, 特别是初学者, 他们要么记不住这些数字代号, 要么根本就不知道. 当在阅读源代码的时候, 遇到这样的代码段, 那么就需要花费时间去查找 27 和按键的对应关系. 当然, 你也可以在后边加上注释. 不过, 在这里我建议你使用一个常量名来代替, 比如: KEY_ESC = 27. 这样更加直观易懂!
2. 标识符(identifiers)
我们经常需要获取某个元素 (评论, 博客, 用户, 等等) 的标识符, 然后做一些计算. 比如:
var id = $(this).attr('id').substring(8);
正如我们已经提过, 阅读这段代码的开发者需要去推测为什么用 8.
我们再举一个例子(来自一个实际的项目):
var last_id = $('#answer_pid' + id + 'li:first div').attr('id').substr(7);
html 的布局稍有变动, 都将导致这部分代码出错.
我们再看一个:
- <div class="comment" id="comment_123">
- </div>
- var id = $(this).attr('id').substring("comment_".length);
这段代码好一点, 至少没有使用看不懂的数字, 但 JavaScript 代码还是和 HTML 有太多的绑定.
我们可以使用 data-* 语法:
<div class="comment" data-id="123"></div>
然后, 用更加简洁的语法来获取属性值:
var id = $(this).attr('data-id');
或则:
- var id = $(this).data('id');
- 3. $.post
我们都知道 jQuery 有一个 Ajax 函数 $.Ajax. 对于具体的操作, 还有 $.get, $..load, $.post, 等等. 这些函数被我们频繁的使用(上传一段脚本, JSON 文件, 执行一个 post 请求), 它们底层都是用 $.Ajax 实现.
对于个人而言, 我从不使用这些简化版的函数, 接下来我会告诉你为什么.
对于初学者或则经验不足的开发者, 你会发现写代码也会分为不同的层次:
a. 初级
- $.post(url, data, function(data) {
- data = $.parseJSON(data);
- //...
- });
b. 考虑异常情况
- $.post(url, data, function(data) {
- try {
- data = $.parseJSON(data);
- } catch (e) {
- return;
- }
- //...
- });
c. 如果认真阅读 $.post 的文档, 我们就会发现最后一个参数应该是数据的类型 dataType, 但是我发现在大多数开发者写的代码中都忘记了!
- $.post(url, data, function(data) {
- //...
- }, 'json');
我发现初学者很少在项目开发中考虑错误处理, 他们通常不愿意多花 5 分钟额外的时间去完善这部分工作, 或则自信的认为代码不会有问题.
如果他们决定添加错误处理到 $.post, 通常会像下面这样写:
- $.post(url, data, function(data) {
- //...
- }, 'json').error(function() {
- //...
- });
这样写是很难理解的! 每次都去写出错处理非常的繁琐和耗时, 你可以定义一个默认的错误处理句柄 (default error handler) 来应对所有的 Ajax 请求. 对于全局的异常, 产品上线以后可以使用 fundebug 的 JavaScript 插件 https://docs.fundebug.com/notifier/javascript/ 来抓取.
- $.ajaxSetup({
- error: function() {
- // Error modal
- }
- });
我们回到 $.post 函数, 上面的写法很难读懂, 而且 dataType 作为最后一个参数很容易遗漏. 我个人认为, 如下的写法更加容易阅读和维护:
- $.Ajax({
- type: "POST",
- url: url,
- data: data,
- dataType: "json",
- success: function(data) {
- //...
- },
- error: function() {
- //...
- }
- });```
- ### 4. 多元素事件
有时候, 我们需要给页面元素绑定对应的事件(删除消息的按钮). 经常, 我们会这样实现:
- ```JS
- $('.comment a.delete').click(function(){
- //...
- });
问题在于, 如果我们要把同一个事件绑定到一个新的元素(比如一个新载入的评论). 我浏览过很多解法, 其中一个典型的解法是重新定义所有元素上的事件:
- $('.comment a.delete').unbind('click').click(function() {
- //
- });
在 jQuery 1.7 中有 on 事件, 可以把事件绑定到某个行为, 并且可以通过选择器 (selector) 过滤元素:
- $('body').on('click', 'a.external', function(e) {
- // 该函数只会绑定到那些有 external 类的元素上
- });
值得一提的是, 上面的代码对于动态生成的对象也有效. 应当大力提倡, 不过也要小心! 如下代码会导致效率的降低, 拖慢浏览器的速度:
- $('body').on('mousemove', selector, function() {
- //...
- });
5. 带命名空间的事件(namespaced events)
带命名空间的事件 (namespaced events) 在 jQuery 1.2 就被加入了, 但是没有几个人用. 我敢打赌你也不知道!
举个例子:
- $('a').on('click', function() {
- // Handler 1
- });
- $('a').on('click', function() {
- // Handler 2
- });
如果我们想要移除第二个 handler, 使用 $('a').off('click')确会把两个 handler 都移除掉!
但是如果使用带命名空间的事件, 就可以搞定:
- $('a').on('click.namespace1', function() {
- //Handler 1
- });
- $('a').on('click.namespace2', function() {
- //Handler 2
- });```
使用如下代码移除:
- ```JS
- $('a').off('click.namespace2');
如果想更多了解, 请参考: Event names and namespaces http://api.jquery.com/on/#event-names
这还只是我在阅读别人代码的时候, 经常遇到的问题中的一小部分. 我希望这篇文章可以帮助大家提高写代码的质量!
来源: http://www.qdfuns.com/article/40048/b15880a631f693b1937529026fc579e8.html