编写可维护的Js代码
基本格式化
can 函数返回布尔值
has 函数返回布尔值
is 函数返回布尔值
get 函数返回非布尔值
set 函数用来保存值
注释
单行注释
- 独占一行,注释前总是有一个空行,缩进与下一行代码保持一致
- 代码行尾部,代码结束到注释之间有一个空格,代码加上注释不应超过单行最大字符数限制,超过了就应放到当前代码行的上方
- 单行注释不应以连续多行注释的形式出现
多行注释
- 最少三行第一行 / , 第二行 与上一行 对齐,最后一行 / (单行多行注释区分开比较好,多行注释风格很多,这里只是一种,找到适合的就好)
/*
*空格 + 注释
*/
- 注释前总是有一个空行,缩进与下一行代码保持一致
- 代码结束到注释之间有一个缩进
添加注释的一般原则
- 需要让代码表达的意思更清晰
- 难以理解的代码
- 可能被认为错误的代码
- 浏览器特性 hack
文档注释
/**
*注释
*@ 变量1 {String} 一个字符串变量
*/
如何添加文档注释
语句和表达式
块语句都应使用花括号
花括号对齐方式,左花括号挡在块语句的第一行末尾
if () {
} else {
}
块语句间隔
语句名,小括号,花括号都没有空格
if(true){
}
小括号左右加空格
if (true) {
}
小括号左右加空格,小括号与小括号内容之间加空格
if ( true ) {
}
switch 语句
缩进
每条 case 语句相对于 switch 关键字缩进一个层级,每条 case 语句后都有一个空行
switch (color) {
case '#000':
break
case '#f00':
break
case '#00F':
break
default:
break
}
case 和 switch 左对齐,且没有空行
switch (color) {
case '#000':
break
case '#00F':
break
default:
break
}
while 语句 尽量避免使用,因为在严格模式下不能运行,而且容易造成对于变量的认知错误
let message = '你好!'
let book = {
name: '少少',
age: 18,
message: '你好吗?'
}
with (book) {
message += name
console.log(message)
}
for 循环 遍历数组
for-in 循环 遍历对象
不仅遍历对象的实例属性同样遍历从原型继承来的属性,往往因意外的结果而终止
变量 函数 运算符
变量声明
在有相关性时,合并变量声明
let value = 10,
result = 10,
i,
len;
函数声明
函数调用间隔
立即调用的函数
const myFunction = function () {
// 函数
}
let value = function () {
return 'string' // 变量
}()
// 好的写法
let value = (function () {
return 'string'
}())
严格模式 "use strict"
不在全局使用严格模式
function () {
"use strict"
}
(function () {
"use strict"
function () {
}
function () {
}
function () {
}
})()
相等 JavaScript 有强制类型转换机制
UI 层的松耦合
将 html 和 js 代码分离开
避免使用全局变量
全局变量带来的问题
意外的全局变量
单全局变量
创建的这个唯一全局对象名是独一无二的(不会和内置API产生冲突),并将所有的功能代码全都挂载到这个全局对象上,因此每个可能的全局变量都会成为你唯一的全局对象的属性,从而不会创建多个全局变量
// 再比如表示三本书
// 方法一
function Book (name) {
return `书名:${name}`
}
const Book1 = Book("name1")
const Book2 = Book("name2")
const Book3 = Book("name3")
console.log(Book1, Book2, Book3)
// 单全局变量
class Books {
Book1 = Book("name1")
Book2 = Book("name2")
Book3 = Book("name3")
Book (name) {
return `书名:${name}`
}
}
console.log(Books.Book1, Books.Book2, Books.Book3)
/*
*其他例子: jQuery 定义了 $ 和 jQuery
*以及vue 定义了 Vue
*/
命名空间(在类中定义分组,方便管理)
class My {
dom = {
addDom () {
...
},
removeDom () {
...
}
...
}
event = {
onClick () {
...
},
oninput () {
...
}
...
}
}
事件处理
典型用法 (流水账式写法)
// 常见但是不推荐的写法
handleClick (event) {
const popup = document.getElementById("popup")
popup.style.left = event.clientX
popup.style.top = event.clientY
popup.className = "show"
}
隔离应用逻辑 应用逻辑和用户行为应该区分开(一个函数只做一件事,便于函数复用)
clas Myapp {
handleClick (event) {
this.showPopup(event)
},
showPopup (event) {
const popup = document.getElementById("popup")
popup.style.left = event.clientX
popup.style.top = event.clientY
popup.className = "show"
}
}
不要分发事件对象 应用逻辑不应该依赖 event 对象来完成功能(便于测试,便于函数复用)
clas Myapp {
handleClick (event) {
// 事件处理程序是接触 event 对象的唯一函数 (一个函数只做一件事)
event.preventDefault()
event.stopPropagation()
// 传入应用逻辑
this.showPopup(event.clientX, event.clientY)
},
showPopup (x, y) {
const popup = document.getElementById("popup")
popup.style.left = x
popup.style.top = y
popup.className = "show"
}
}
广州品牌设计公司https://www.houdianzi.com PPT模板下载大全https://redbox.wode007.com
避免空比较
检测数组 (es5已有自带检测方法)
// 关注对象能做什么,而不是他是什么
function isArr(value) {
return typeof value.sort === 'function'
}
// 更为优雅有效的解决方案 (兼容 IE6 以下版本)
function isArray (value) {
if (typeof Array.isArray === 'function') {
return Array.isArray(value) // 自带判断数组方法
} else {
// 某个值内置的 toString 在所有的浏览器中都会返回标准的字符串结果
return Object.prototype.toString.call(value) === '[object Array]'
}
}
检测属性是否存在
不好的写法,通过给定的名字检查属性的值
let myObject = {
count: 0
}
if (myObject['count']) {
// 存在但不执行
}
好的写法,通过 in 运算符或者 hasOwnPrperty()
let myObject = {
count: 0
}
if ('count' in myObject) { // in 只检查属性是否存在于对象实例或者对象原型
// 执行
}
if (myObject.hasOwnPrperty('count')) { // 只检查是否存在于对象实例
// 执行
}
将配置数据从代码中分离出来
什么是配置数据 写死在代码里,且将来可能会被修改
抛出自定义错误
JavaScript 抛出错误的方法
throw new Error('错误信息')
如何书写抛出的错误文本
throw new Error('函数名: 可能的原因')
什么时候抛出错误
try-catch 语句 catch 代码块不能省略或留空
能在错误抛出前解析它;
抛出错误会中断 js 进程, 使用 try-catch 则不会中断 js 进程
个人理解: try-catch 语句可以用在自己知道可能会出错但是不能明确的知道错误原因,
或者在报错后仍需继续报错代码块之后语句的情况下
不是自己的对象不要动
什么是自己的对象
对象的使用原则
如何使用?
防止对象被修改

浙公网安备 33010602011771号