全局变量
全局变量带来的问题:
-
命名冲突
-
代码脆弱性
- 任一地方修改了全部变量,都可能使所有使用全局变量的地方出错
-
难以测试
避免意外定义全局变量
-
var
function fn(){ var count = 10 name = 'jack' }name将创建为全局变量,使用呢eslint等工具可以有效防范
单全局变量
创建一个唯一的全局对象,将所有的其他全局变量都挂载到该全局对象上,就像jquery等大量第三方库使用该种方式管理全局变量
命名空间
即使使用单全局变量,全局变量内部也可能产生污染,因此可以在全局对象内部以属性的方式创建单独的命名空间:
const $all = {
命名空间1: {},
命名空间2: {}
}
模块化
现在常用的有两种规范ESM规范和CommonJS规范,有兴趣可直接翻阅阮大的博客:Javascript模块化编程
事件处理
核心思想是逻辑分离:即事件逻辑和应用逻辑的分离.先来一个常见未分离逻辑的写法,后文中以此为基础进行讨论
function handleClick = function(event){
....
}
dom.addEventListener('click',handleClick)
隔离应用逻辑
上述案例中事件处理程序包含了应用逻辑,这段应用逻辑如果将来可能会在其他地方出现(比如这里的应用逻辑是弹个弹窗),那么将不可避免的写重复代码,最好是将应用逻辑和事件处理逻辑分离:
const appLication = {
handclick(event){
this.showModel()
},
showModel(event){
....
}
}
dom.addEventListener('click',(event) => {
appLication.handclick(event)
})
这么做,将应用逻辑剥离到showModel中达到多种情况下复用的目的,
不要分发事件对象
然而上述的代码还不够完美,event对象一直在来回传递,即使在showModel中不需要使用event的全部属性,同是也导致不容易测试showModel函数,因此可以进一步将需要的值传递给showModel
const appLication = {
handclick(event){
// 作为事件逻辑函数,像阻止事件冒泡,阻止默认行为都可以在这里做,而不会将这些事件逻辑融合到应用逻辑中
this.showModel(event.clientX,event.clientY)
},
showModel(x,y){
....
}
}
dom.addEventListener('click',(event) => {
appLication.handclick(event)
})
类型判断
判断原始值
推荐使用typeof,检测string,undefined,number,boolean,symbol是非常安全的
判断引用值
- 数组: Array.isArray()
- 对象: Object.prototype.toString.call() 返回
[object Object],(ps: 总感觉这个最靠谱) - 函数: typeof
- 自定义,日期,正则: instanceof
判断属性
推荐使用in或hasOwnProperty
-
in
- 属性自身存在或继承自原型都会返回true
-
hasOwnProperty
- 检测自身是否包含该属性,不包括原型链中的属性