1 /* 2 1.类型types 3 原始值:存取直接作用于它自身 4 string 5 number 6 boolean 7 null 8 undefined 9 var foo=1; 10 var bar=foo; 11 bar=9; 12 console.log(foo,bar);//=>1,9 13 复杂类型:存取时作用于它自身值的引用 14 object 15 array 16 function 17 var foo=[1,2]; 18 var bar=foo; 19 bar[0]=9; 20 console.log(foo,bar);//=>1,9 21 2.对象objects 22 使用直接量创建对象 23 //bad 24 var item=new Object(); 25 //good 26 var item={}; 27 不要使用保留字作为键名,它们在IE8下不工作 28 //bad 29 var superman={ 30 default:{clark:‘kent’}, 31 private:ture; 32 }; 33 //good 34 var superman={ 35 default:{clark:‘kent’}, 36 hidden:ture; 37 }; 38 使用同义词替换需要使用的保留字 39 //bad 40 var superman={ 41 class:'alien' 42 }; 43 //bad 44 var superman={ 45 klass:'alien' 46 }; 47 //good 48 var superman={ 49 type:'alien' 50 }; 51 3.数组arrays 52 使用直接量创建数组 53 //bad 54 var items=new Array(); 55 //good 56 var items=[]; 57 向数组增加元素时使用Array#push来替代直接赋值 58 var someStack=[]; 59 //bad 60 someStack[someStack.length]='abcdefghi'; 61 //good 62 someStack.push('abcdefghi'); 63 当你需要拷贝数组时,使用Array#slice. 64 var len=items.length; 65 var itemsCopy=[]; 66 var i; 67 //bad 68 for(i=0;i<len;i++){ 69 itemsCopy[i]=items[i]; 70 } 71 //good 72 itemsCopy=items.slice(); 73 使用Array#slice将类数组对象转换成数组 74 function trigger(){ 75 var args=Array.prototype.slice.call(arguments); 76 } 77 4.字符串strings 78 使用单引号‘’包裹字符串 79 //bad 80 var name=“bob parr"; 81 //good 82 var name='bob parr'; 83 //bad 84 var fullName="bob"+this.lastName; 85 //good 86 var fullName=‘bob’+this.lastName; 87 超过100个字符的字符串应该使用链接字符写成多行。 88 注:若过度使用,通过连接符连接的长字符串可能会影响性能。 89 //bad 90 var errorMessage='this is a super long error that was thrown because of batman.when you stip to think'; 91 var errorMessage='this is a super long error that was thrown\ 92 because of batman.\ 93 when you stip to think'; 94 //good 95 errorMessage='this is a super long error that was thrown'+ 96 'because of batman.'+ 97 'when you stip to think'; 98 程序化生成的字符串使用Array#join连接而不是使用连接符。尤其是IE下; 99 var items; 100 var messages; 101 var length; 102 var i; 103 104 messages=[{ 105 state:'success', 106 message:'this one worked' 107 },{ 108 state:'success', 109 message:'this one worked as well' 110 },{ 111 state:'error', 112 message:'this one did not work' 113 }]; 114 legnth=messages.length; 115 //bad 116 function inbox(messages){ 117 items='<ul>'; 118 for(i=0;i<length;i++){ 119 items+='<li>'+messages[i].message+'</li>'; 120 } 121 return items+'</ul>'; 122 } 123 //good 124 function inbox(messages){ 125 items=[]; 126 for(i=0;i<length;i++){ 127 items[i]='<li>'+messages[i].message+'</li>'; 128 } 129 return '<ul>'+items.join('')+'</ul>'; 130 } 131 5.函数functions 132 函数表达式 133 //匿名函数表达式 134 var anonymous=function(){ 135 return true; 136 } 137 //命名函数表达式 138 var named=function named(){ 139 return true; 140 } 141 //立即调用的函数表达式(IIFE) 142 (function(){ 143 console.log('welcome to the internet'); 144 }()); 145 永远不要在一个非函数代码块(if、while等)中声明一个函数,把那个函数赋给一个变狼。浏览器允许你这么做,但它们的解析表现不一致。 146 注:ECMA-262把块定义为一组语句。函数声明不是语句。 147 //bad 148 if(currentUser){ 149 function test(){ 150 console.log('Nope'); 151 } 152 } 153 //good 154 var test; 155 if(currentUser){ 156 test=function test(){ 157 console.log('Yup'); 158 }; 159 } 160 永远不要把参数命名为arguments。这将取代函数作用域内的arguments对象。 161 // bad 162 function nope(name, options, arguments) { 163 // ...stuff... 164 } 165 166 // good 167 function yup(name, options, args) { 168 // ...stuff... 169 } 170 171 6.属性properties 172 使用.来访问对象的属性。 173 var luke={ 174 jedi:ture; 175 age:28 176 }; 177 //bad 178 var isJedi=luke['jedi']; 179 //good 180 var isJedi=luke.jedi; 181 当通过变量访问属性时,使用中括号[] 182 var luke={ 183 jedi:ture; 184 age:28 185 }; 186 function getProp(prop){ 187 return luke[prop]; 188 } 189 var isJedi=getProp('jedi'); 190 7.变量varibles 191 总是使用var来声明变量。不这么做将导致产生全局变量。我们要避免污染全局命名空间。 192 //bad 193 superPower=new SuperPower(); 194 //good 195 var superPower=new SuperPower(); 196 使用var声明每一个变量。这样做的好处是增加新变量将变得更加容易,而且你永远不用再担心调换错;跟,。 197 //good 198 var items=getItems(); 199 var goSportsTeam=ture; 200 var dr='z'; 201 最后再声明未赋值的变量,当你需要引用前面的变量赋值时这将变的很有用。 202 var items=getItems(); 203 var goSportsTeam=ture; 204 var dragonball; 205 var i; 206 在作用域顶部声明变量。这将帮助你避免变量声明提升相关的问题。 207 8.提升hoisting 208 变量声明会提升至作用域顶部,但赋值不会。 209 匿名函数表达式会提升它们的变量名,但不会提升函数的赋值。 210 命名函数表达式会提升函数名,但不会提升函数名或函数体。 211 函数声明提升它们的名字和函数体。 212 function example() { 213 superPower(); // => Flying 214 215 function superPower() { 216 console.log('Flying'); 217 } 218 } 219 9.比较预算法&等号comparison-operators-equality 220 优先使用===和!==而不是==和!= 221 条件表达式例如if语句通过抽象方法ToBoolean强制计算它们的表达式并且总是遵守下面的规则。 222 对象被计算为true 223 undefined被计算为false 224 Null被计算为false 225 布尔值被计算为布尔值 226 数字如果是+0、-0或NaN被计算为false,负责为true 227 字符串如果是空字符串‘’被计算为false,负责为true 228 if([0]){ 229 //true 230 //一个数组就是一个对象,对象被计算为true 231 } 232 使用快捷方式 233 //bad 234 if(name!==''){ 235 //stuff 236 } 237 //good 238 if(name){ 239 //stuff 240 } 241 //bad 242 if(collection.length>0){ 243 //stuff 244 } 245 //good 246 if(collection.length){ 247 //stuff 248 } 249 10.块blocks 250 使用大括号包裹所有的多行代码块 251 if(test){ 252 return false; 253 } 254 function(){ 255 return false; 256 } 257 如果通过if和else使用多行代码块,把else放在if代码块关闭括号的同一行 258 if(test){ 259 thing1(); 260 }else{ 261 thing2(); 262 } 263 11.注释comments 264 使用/+*..*+/作为多行注释,包含描述、指定所有参数和返回值得类型和值 265 使用//作为单行注释,在评论对象上面另起一行使用单行注释。在注释钱插入空行 266 // good 267 // is current tab 268 var active = true; 269 270 // good 271 function getType() { 272 console.log('fetching type...'); 273 274 // set the default type to 'no type' 275 var type = this.type || 'no type'; 276 277 return type; 278 } 279 使用FIXME或TODO的前缀可以帮助其他开发者快速了解这是一个需要复查的问题 280 //FIXME:shouldn`t use a global here 281 //TODO:total should be configurable by an options param 282 12.空白whitespace 283 使用2个空格作为缩进 284 在大括号前方一个空格 285 function test() { 286 287 } 288 在控制语句(if、while等)的小括号前放一个空格。在函数调用及声明中,不在函数参数列表前加空格。 289 使用空格把运算符隔开。 290 var x = y + 5; 291 在文件末尾插入一个空行 292 在使用长方法链时进行缩进。使用前面的点.强调这是方法调用而不是新语句 293 $('items') 294 .find('selected') 295 .highlight() 296 .end() 297 .find('open') 298 .updateCount(); 299 在块末和新语句前插入空行。 300 13.逗号commas 301 行首逗号:不需要 302 额外的行末逗号:不需要 303 var story=[ 304 once, 305 upon, 306 aTime 307 ]; 308 14.分号semicolons 309 使用分号 310 //good 311 (function() { 312 var name='sky'; 313 return name; 314 })(); 315 //good (防止函数在两个IIFE合并时被当成一个参数) 316 ;(function() { 317 var name='sky'; 318 return name; 319 })(); 320 15.类型转化type-casting-coercion 321 在语句开始时执行类型转换 322 使用parseInt转换数字时总是带上类型转换的基数; 323 var inputValue='4'; 324 //bad 325 var val=new Number(inputValue); 326 //bad 327 var val=+inputValue; 328 //bad 329 var val=parseInt(inputValue); 330 //good 331 var val=Number(inputValue); 332 //good 333 var val=parseInt(inputValue,10); 334 布尔: 335 var age=0; 336 //bad 337 var hasAge=new Boolean(age); 338 //good 339 var hasAge=Boolean(age); 340 //good 341 var hasAge=!!age; 342 343 16.命名规则naming-conventions 344 避免单字母命名,命名应具备描述下 345 使用驼峰式命名对象、函数和实例 346 使用帕卡斯式命名构造函数或类 347 //bad 348 function user(){ 349 this.namme=options.name; 350 } 351 //good 352 function User(){ 353 this.namme=options.name; 354 } 355 var good=new User(){ 356 name:'hip'; 357 } 358 不要使用下划线前/后缀,javascript没有私有属性或方法的概念 359 //bad 360 this._firstName_=''; 361 //good 362 this.firstName=''; 363 不要保存this的应用,使用Function#bind 364 //bad 365 function(){ 366 var self=this; 367 return function(){ 368 console.log(self); 369 }; 370 } 371 //good 372 function() { 373 return function() { 374 console.log(this); 375 }.bind(this); 376 } 377 给函数命名,这在做堆栈轨迹时很有帮助 378 //bad 379 var log=function(msg) { 380 console.log(msg); 381 }; 382 //good 383 var log=function log(msg) { 384 console.log(msg); 385 } 386 387 17.存取器accessors 388 属性的存取函数不是必须的 389 如果你需要存取函数时使用getVal()和setVal('hello'),便于理解函数的用途 390 如果属性时布尔值,使用isVal()或hasVal() 391 18.事件events 392 当给事件附加数据时,传入一个哈希而不是原始值。这样可以让后面的贡献者增加更 393 多数据到事件数据而无需找出并更新事件的每一个处理器。 394 //bad 395 $(this).trigger('listingUpdated','listing.id'); 396 //good 397 $(this).trigger('listingUpdated',{listingId:listing.id}); 398 399 400 401 */