javascript书写规范.doc_第1页
javascript书写规范.doc_第2页
javascript书写规范.doc_第3页
javascript书写规范.doc_第4页
javascript书写规范.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Javascript书写规范:1. 文件编码统一为utf-8;2. 书写过程过, 每行代码结束必须有分号;3. 库引入: 原则上仅引入jQuery库;4. 变量命名: 以下划线链接每个单词,类型_变量名;s:表示字符串;n:表示数字;b:表示逻辑;a:表示数组;r:表示正则表达式;f:表示函数;o:表示以上未涉及到的其他对象;变量在作用域的顶部申明。5.常量:全部大写,以下划线分隔 如网站的URL,域,图片目录路径,js和css用到的目录路径;6. 类命名: 首字母大写, 驼峰式命名. 如 Comment;7. 函数命名: 首字母小写驼峰式命名. 如getUserName();8.类中私有方法,以下划线+方法名标注,私有方法不能在类外被调用。9. 命名语义化, 尽可能利用英文单词或其缩写;10. 代码结构明了化, 加适量注释. 提高函数重用率;1)大功能区块的功能描述(类,函数)/*功能描述参数描述返回值*/2)单行的注释(放在行末尾)/注释11. 注重与html分离, 减小reflow, 注重性能.12.Dom中自定义的class,以j_classname的形式13.把外部JavaScript文件放在HTML底部,的前面14.优化循环(循环体中若有Dom操作,应该把Dom操作提到循环体外;在同一作用域内,Dom选择赋值给一局部变量。)15.单引号和双引号为了避免混乱,我们建议在HTML中使用双引号,在JavaScript中使用单引号。/html/JavaScriptdocument.write();/一段混用的jQuery代码$(h1).after(目录);16.使用更简单的格式来写innerscript/早期的代码可能是这样的./现在不用language属性了.17.总是检查数据要检查你的方法输入的所有数据,一方面是为了安全性,另一方面也是为了可用性。用户随时随地都会输入错误的数据。这不是因为他们蠢,而是因为他们很忙,并且思考的方式跟你不同。用typeof方法来检测你的function接受的输入是否合法。18.避免混入其他技术,js不直接控制css详细的设置,可控制classname19.避免全局变量(类名空间App.dialog.)全局变量和全局函数是非常糟糕的。因为在一个页面中包含的所有JavaScript都在同一个域中运行。所以如果你的代码中声明了全局变量或者全局函数的话,后面的代码中载入的脚本文件中的同名变量和函数会覆盖掉(overwrite)你的。/糟糕的全局变量和全局函数var current = null;function init().function change().function verify().解决办法有很多,Christian Heilmann建议的方法是:/如果变量和函数不需要在“外面”引用,那么就可以使用一个没有名字的方法将他们全都包起来。(function() var current = null; function init(). function change(). function verify().)();/如果变量和函数需要在“外面”引用,需要把你的变量和函数放在一个“命名空间”中/我们这里用一个function做命名空间而不是一个var,因为在前者中声明function更简单,而且能保护隐私数据myNameSpace = function() var current = null; function init(). function change(). function verify(). /所有需要在命名空间外调用的函数和属性都要写在return里面 return init:init, /甚至你可以为函数和属性命名一个别名 set:change ();20.声明变量的话,总是用varJavaScript中的变量可能是全局域或者局部域,用var声明的话会更加直观。21.避免使用eval()方法(ajax数据请求验证)JavaScript中的eval()方法是在运行时把任何代码当作对象来计算/运行的方法。实际上由于安全性的缘故,大部分情况下都不应该用 eval(),总是有一种更“正确”的方法来完成同样的工作的。基本原则是,eval is evil,在任何时候都不要用它,除非你是一个老手,并且知道你不得不这样做。22.不要偷懒省略”和从技术上说,你可以忽略很多花括号和分号。/虽然看上去很不对头,大部分浏览器都能正确解析这段代码if(someVariableExists) x = false/这个代码看上去更不对头了,咋眼一看似乎下面的句都被执行了/实际上只有x=false在if中if(someVariableExists) x = false anotherFunctionCall();所以,要记住的原则是:1.永远不要省略分号;2.不要省略花括号,除非在同一行中。/这样是OK的if(2 + 2 = 4) return nicely done;23.获取对象属性的时候用方括号而不是点号在JavaScript中取得某对象的属性有两种方法:/点号标记MyOperty/方括号标记MyObjectproperty如果是用点号标记取得对象的属性,属性名称是硬编码,无法在运行时更改;而用方括号的话,JavaScript会求得方括号内值然后通过计算结果来求得属性名。也就是说用方括号标记的方式,属性名称可以是硬编码的,也可以是变量或者函数返回值。/这样是不行的MyObject.value+i/这样就没有问题MyObjectvalue+i24.for in语句遍历一个对象中的所有条目的时候,用for in语句是非常方便的。但有时候我们不需要遍历对象中的方法,如果不需要的话,可以加上一条filter。/加上了一个过滤器的for in语句for(key in object) if(object.hasOwnProperty(key) .then do something. 25.代码排版缩进 tab长度为4行长度 ,控制在可视范围内,以一个分号结束花括号,如果是一个代码段,花括号紧跟在语句的后面文件功能定义base:网站常量common:我,自动延伸高,插入表情,统计字数,全选,收藏心跳,分享站外,关注,弹窗,拖拽,top至顶page制作要求:、弹窗:按设计图还原即可,不用考虑弹窗的位置。、对于网页代码,一定要保持足够的精简,拷贝的无用代码一定要删除。、标签的语义化,不能滥用标签。、尽可能不用标签ID来控制样式。后端:js功能性修改,需要通知前端。全局命名空间污染与 IIFE总是将代码包裹成一个 IIFE(Immediately-Invoked Function Expression),用以创建独立隔绝的定义域。这一举措可防止全局命名空间被污染。IIFE 还可确保你的代码不会轻易被其它全局命名空间里的代码所修改(i.e. 第三方库,window 引用,被覆盖的未定义的关键字等等)。不推荐1. var x = 10,2. y = 100;3. 4. / Declaring variables in the global scope is resulting in global scope pollution. All variables declared like this5. / will be stored in the window object. This is very unclean and needs to be avoided.6. console.log(window.x + + window.y);推荐1. / We declare a IIFE and pass parameters into the function that we will use from the global space2. (function(log, w, undefined)3. use strict;4. 5. var x = 10,6. y = 100;7. 8. / Will output true true9. log(w.x = undefined) + + (w.y = undefined);10. 11. (window.console.log, window);IIFE(立即执行的函数表达式)无论何时,想要创建一个新的封闭的定义域,那就用 IIFE。它不仅避免了干扰,也使得内存在执行完后立即释放。所有脚本文件建议都从 IIFE 开始。立即执行的函数表达式的执行括号应该写在外包括号内。虽然写在内还是写在外都是有效的,但写在内使得整个表达式看起来更像一个整体,因此推荐这么做。不推荐1. (function()();推荐1. (function()();so,用下列写法来格式化你的 IIFE 代码:1. (function()2. use strict;3. 4. / Code goes here5. 6. ();如果你想引用全局变量或者是外层 IIFE 的变量,可以通过下列方式传参:1. (function($, w, d)2. use strict;3. 4. $(function() 5. w.alert(d.querySelectorAll(div).length);6. );7. (jQuery, window, document);严格模式ECMAScript 5 严格模式可在整个脚本或独个方法内被激活。它对应不同的 javascript 语境会做更加严格的错误检查。严格模式也确保了 javascript 代码更加的健壮,运行的也更加快速。严格模式会阻止使用在未来很可能被引入的预留关键字。你应该在你的脚本中启用严格模式,最好是在独立的 IIFE 中应用它。避免在你的脚本第一行使用它而导致你的所有脚本都启动了严格模式,这有可能会引发一些第三方类库的问题。不推荐1. / Script starts here2. use strict;3. 4. (function()5. 6. / Your code starts here7. 8. ();推荐1. (function()2. use strict;3. 4. / Your code starts here5. 6. ();变量声明总是使用var来声明变量。如不指定 var,变量将被隐式地声明为全局变量,这将对变量难以控制。如果没有声明,变量处于什么定义域就变得不清(可以是在 Document 或 Window 中,也可以很容易地进入本地定义域)。所以,请总是使用 var 来声明变量。采用严格模式带来的好处是,当你手误输入错误的变量名时,它可以通过报错信息来帮助你定位错误出处。不推荐1. x = 10;2. y = 100;推荐1. var x = 10,2. y = 100;理解 JavaScript 的定义域和定义域提升在 JavaScript 中变量和方法定义会自动提升到执行之前。JavaScript 只有 function 级的定义域,而无其他很多编程语言中的块定义域,所以使得你在某一 function 内的某语句和循环体中定义了一个变量,此变量可作用于整个 function 内,而不仅仅是在此语句或循环体中,因为它们的声明被 JavaScript 自动提升了。我们通过例子来看清楚这到底是怎么一回事:原 function1. (function(log)2. use strict;3. 4. var a = 10;5. 6. for(var i = 0; i a; i+) 7. var b = i * i;8. log(b);9. 10. 11. if(a = 10) 12. var f = function() 13. log(a);14. ;15. f();16. 17. 18. function x() 19. log(Mr. X!);20. 21. x();22. 23. (window.console.log);被 JS 提升过后1. (function(log)2. use strict;3. / All variables used in the closure will be hoisted to the top of the function4. var a,5. i,6. b,7. f;8. / All functions in the closure will be hoisted to the top9. function x() 10. log(Mr. X!);11. 12. 13. a = 10;14. 15. for(i = 0; i a; i+) 16. b = i * i;17. log(b);18. 19. 20. if(a = 10) 21. / Function assignments will only result in hoisted variables but the function body will not be hoisted22. / Only by using a real function declaration the whole function will be hoisted with its body23. f = function() 24. log(a);25. ;26. f();27. 28. 29. x();30. 31. (window.console.log);根据以上提升过程,你是否可理解以下代码?有效代码1. (function(log)2. use strict;3. 4. var a = 10;5. 6. i = 5;7. 8. x();9. 10. for(var i; i a; i+) 11. log(b);12. var b = i * i;13. 14. 15. if(a = 10) 16. f = function() 17. log(a);18. ;19. f();20. 21. var f;22. 23. 24. function x() 25. log(Mr. X!);26. 27. 28. (window.console.log);正如你所看到的这段令人充满困惑与误解的代码导致了出人意料的结果。只有良好的声明习惯,也就是下一章节我们要提到的声明规则,才能尽可能的避免这类错误风险。提升声明为避免上一章节所述的变量和方法定义被自动提升造成误解,把风险降到最低,我们应该手动地显示地去声明变量与方法。也就是说,所有的变量以及方法,应当定义在 function 内的首行。只用一个var关键字声明,多个变量用逗号隔开。不推荐1. (function(log)2. use strict;3. 4. var a = 10;5. var b = 10;6. 7. for(var i = 0; i 10; i+) 8. var c = a * b * i;9. 10. 11. function f() 12. 13. 14. 15. var d = 100;16. var x = function() 17. return d * d;18. ;19. log(x();20. 21. (window.console.log);推荐1. (function(log)2. use strict;3. 4. var a = 10,5. b = 10,6. i,7. c,8. d,9. x;10. 11. function f() 12. 13. 14. 15. for(i = 0; i 10; i+) 16. c = a * b * i;17. 18. 19. 20. 21. d = 100;22. x = function() 23. return d * d;24. ;25. log(x();26. 27. (window.console.log);把赋值尽量写在变量申明中。不推荐1. var a,2. b,3. c;4. 5. a = 10;6. b = 10;7. c = 100;推荐1. var a = 10,2. b = 10,3. c = 100;总是使用带类型判断的比较判断总是使用=精确的比较操作符,避免在判断的过程中,由 JavaScript 的强制类型转换所造成的困扰。如果你使用=操作符,那比较的双方必须是同一类型为前提的条件下才会有效。如果你想了解更多关于强制类型转换的信息,你可以读一读Dmitry Soshnikov 的这篇文章。在只使用=的情况下,JavaScript 所带来的强制类型转换使得判断结果跟踪变得复杂,下面的例子可以看出这样的结果有多怪了:1. (function(log)2. use strict;3. 4. log(0 = 0); / true5. log( = false); / true6. log(1 = true); / true7. log(null = undefined); / true8. 9. var x = 10. valueOf: function() 11. return X;12. 13. ;14. 15. log(x = X);16. 17. (window.console.log);明智地使用真假判断当我们在一个 if 条件语句中使用变量或表达式时,会做真假判断。if(a = true)是不同于if(a)的。后者的判断比较特殊,我们称其为真假判断。这种判断会通过特殊的操作将其转换为 true 或 false,下列表达式统统返回 false:false,0,undefined,null,NaN,(空字符串).这种真假判断在我们只求结果而不关心过程的情况下,非常的有帮助。以下示例展示了真假判断是如何工作的:1. (function(log)2. use strict;3. 4. function logTruthyFalsy(expr) 5. if(expr) 6. log(truthy);18. else 19. log(falsy);20. 21. 22. 23. logTruthyFalsy(true); / truthy24. logTruthyFalsy(1); / truthy25. logTruthyFalsy(); / truthy26. logTruthyFalsy(); / truthy27. logTruthyFalsy(0); / truthy28. 29. logTruthyFalsy(false); / falsy30. logTruthyFalsy(0); / falsy31. logTruthyFalsy(undefined); / falsy32. logTruthyFalsy(null); / falsy33. logTruthyFalsy(NaN); / falsy34. logTruthyFalsy(); / falsy35. 36. (window.console.log);变量赋值时的逻辑操作逻辑操作符|和&也可被用来返回布尔值。如果操作对象为非布尔对象,那每个表达式将会被自左向右地做真假判断。基于此操作,最终总有一个表达式被返回回来。这在变量赋值时,是可以用来简化你的代码的。不推荐7. if(!x) 8. if(!y) 9. x = 1;10. else 11. x = y;12. 13. 推荐1. x = x | y | 1;这一小技巧经常用来给方法设定默认的参数。1. (function(log)2. use strict;3. 4. function multiply(a, b) 5. a = a | 1;6. b = b | 1;7. 8. log(Result + a * b);9. 10. 11. multiply(); / Result 112. multiply(10); / Result 1013. multiply(3, NaN); / Result 314. multiply(9, 5); / Result 4515. 16. (window.console.log);分号总是使用分号,因为隐式的代码嵌套会引发难以察觉的问题。当然我们更要从根本上来杜绝这些问题1。以下几个示例展示了缺少分号的危害:1. / 1.2. MyCtotype.myMethod = function() 3. return 42;4. / No semicolon here.5. 6. (function() 7. / Some initialization code wrapped in a function to create a scope for locals.8. )();9. 10. 11. var x = 12. i: 1,13. j: 214. / No semicolon here.15. 16. / 2. Trying to do one thing on Internet Explorer and another on Firefox.17. / I know youd never write code like this, but throw me a bone.18. ffVersion, ieVersionisIE();19. 20. 21. var THINGS_TO_EAT = apples, oysters, sprayOnCheese / No semicolon here.22. 23. / 3. conditional execution a la bash24. -1 = resultOfOperation() | die();So what happens?1. JavaScript 错误 首先返回 42 的那个 function 被第二个 function 当中参数传入调用,接着数字 42 也被“调用”而导致出错。2. 八成你会得到 no such property in undefined 的错误提示,因为在真实环境中的调用是这个样子:xffVersion, ieVersionisIE().3. die总是被调用。因为数组减 1 的结果是NaN,它不等于任何东西(无论resultOfOperation是否返回NaN)。所以最终的结果是die()执行完所获得值将赋给THINGS_TO_EAT.Why?JavaScript 中语句要以分号结束,否则它将会继续执行下去,不管换不换行。以上的每一个示例中,函数声明或对象或数组,都变成了在一句语句体内。要知道闭合圆括号并不代表语句结束,JavaScript 不会终结语句,除非它的下一个 token 是一个中缀符2或者是圆括号操作符。这真是让人大吃一惊,所以乖乖地给语句末加上分号吧。澄清:分号与函数分号需要用在表达式的结尾,而并非函数声明的结尾。区分它们最好的例子是:1. var foo = function() 2. return true;3. ; / semicolon here.4. 5. function foo() 6. return true;7. / no semicolon here.嵌套函数嵌套函数是非常有用的,比如用在持续创建和隐藏辅助函数的任务中。你可以非常自由随意地使用它们。语句块内的函数声明切勿在语句块内声明函数,在 ECMAScript 5 的严格模式下,这是不合法的。函数声明应该在定义域的顶层。但在语句块内可将函数申明转化为函数表达式赋值给变量。不推荐1. if (x) 2. function foo() 3. 推荐1. if (x) 2. var foo = function() ;3. 异常基本上你无法避免出现异常,特别是在做大型开发时(使用应用开发框架等等)。在没有自定义异常的情况下,从有返回值的函数中返回错误信息一定非常的棘手,更别提多不优雅了。不好的解决方案包括了传第一个引用类型来接纳错误信息,或总是返回一个对象列表,其中包含着可能的错误对象。以上方式基本上是比较简陋的异常处理方式。适时可做自定义异常处理。在复杂的环境中,你可以考虑抛出对象而不仅仅是字符串(默认的抛出值)。1. if(name = undefined) 2. throw 3. name: System Error,4. message: A name should always be specified!5. 6. 标准特性总是优先考虑使用标准特性。为了最大限度地保证扩展性与兼容性,总是首选标准的特性,而不是非标准的特性(例如:首选string.charAt(3)而不是string3;首选 DOM 的操作方法来获得元素引用,而不是某一应用特定的快捷方法)。简易的原型继承如果你想在 JavaScript 中继承你的对象,请遵循一个简易的模式来创建此继承。如果你预计你会遇上复杂对象的继承,那可以考虑采用一个继承库,比如Proto.js by Axel Rauschmayer.简易继承请用以下方式:1. (function(log)2. use strict;3. 4. / Constructor function5. function Apple(name) 6. = name;7. 8. / Defining a method of apple9. Atotype.eat = function() 10. log(Eating + );11. ;12. 13. / Constructor function14. function GrannySmithApple() 15. / Invoking parent constructor16. Atotype.constructor.call(this, Granny Smith);17. 18. / Set parent prototype while creating a copy with Object.create19. GrannySmithAtotype = Object.create(Atotype);20. / Set constructor to the sub type, otherwise points to Apple21. GrannySmithAtotype.constructor = GrannySmithApple;22. 23. / Calling a super method24. GrannySmithAtotype.eat = function() 25. / Be sure to apply it onto our current object with call(this)26. Atotype.eat.call(this);27. 28. log(Poor Grany Smith);29. ;30. 31. / Instantiation32. var apple = new Apple(Test Apple);33. var grannyApple = new GrannySmithApple();34. 35. log(); / Test Apple36. log(grannyA); / Granny Smith37. 38. / Instance checks39. log(apple instanceof Apple); / true40. log(apple instanceof GrannySmithApple); / false41. 42. log(grannyApple instanceof Apple); / true43. log(grannyApple instanceof GrannySmithApple); / true44. 45. / Calling method that calls super method46. grannyApple.eat(); / Eating Granny SmithnPoor Grany Smith47. 48. (window.console.log);使用闭包闭包的创建也许是 JS 最有用也是最易被忽略的能力了。关于闭包如何工作的合理解释。切勿在循环中创建函数在简单的循环语句中加入函数是非常容易形成闭包而带来隐患的。下面的例子就是一个典型的陷阱:不推荐1. (function(log, w)2. use strict;3. 4. / numbers and i is defined in the current function closure5. var numbers = 1, 2, 3,6. i;7. 8. for(i = 0; i numbers.length; i+) 9. w.setTimeout(function() 10. / At the moment when this gets executed the i variable, coming from the outer function scope11. / is set to 3 and the current program is alerting the message 3 times12. / Index 3 with number undefined13. / If you understand closures in javascript you know how to deal with those cases14. / Its best to just avoid functions / new closures in loops as this prevents those issues15. 16. w.alert(Index + i + with number + numbersi);17. , 0);18. 19. 20. (window.console.log, window);接下来的改进虽然已经解决了上述例子中的问题或 bug,但还是违反了不在循环中创建函数或闭包的原则。不推荐1. (function(log, w)2. use strict;3. 4. / numbers and i is defined in the current function closure5. var numbers = 1, 2, 3,6. i;7. 8. for(i = 0; i 1, 1 2, 2 319. w.alert(Index + index + with number + number);20. , 0);21. (i, numbersi);22. 23. 24. (window.console.log, window);接下来的改进已解决问题,而且也遵循了规范。可是,你会发现看上去似乎过于复杂繁冗了,应该会有更好的解决方案吧。不完全推荐1. (function(log, w)2. use strict;3. 4. / numbers and i is defined in the current function closure5. var numbers = 1, 2, 3,6. i;7. 8. / Create a function outside of the loop that will accept arguments to create a9. / function closure scope. This function will return a function that executes in this10. / closure parent scope.11. function alertIndexWithNumber(index, number) 12. return function() 13. w.alert(Index + index + with number + number);14. ;15. 16. 17. / First parameter is a function call that returns a function.18. / -19. / This solves our problem and we dont create a function inside our loop20. for(i = 0; i numbers.length; i+) 21. w.setTimeout(alertIndexWithNumber(i, numbersi), 0);22. 23. 24. (window.console.log, window);将循环语句转换为函数执行的方式问题能得到立马解决,每一次循环都会对应地创建一次闭包。函数式的风格更加值得推荐,而且看上去也更加地自然和可预料。推荐1. (function(log, w)2. use strict;3. 4. / numbers and i is defined in the current function closure5. var numbers = 1, 2, 3,6. i;7. 8. numbers.forEach(function(number, index) 9. w.setTimeout(function() 10. w.alert(Index + index + with number + number);11. , 0);12. );13. 14. (window.console.log, window);eval 函数(魔鬼)eval()不但混淆语境还很危险,总会有比这更好、更清晰、更安全的另一种方案来写你的代码,因此尽量不要使用 evil 函数。this 关键字只在对象构造器、方法和在设定的闭包中使用this关键字。this 的语义在此有些误导。它时而指向全局对象(大多数时),时而指向调用者的定义域(在 eval 中),时而指向 DOM 树中的某一节点(当用事件处理绑定到 HTML 属性上时),时而指向一个新创建的对象(在构造器中),还时而指向其它的一些对象(如果函数被call()和a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论