写好JavaScript的一些编码原则 | 青训营

45 阅读1分钟

1. 各司其职

让HTML、CSS和JavaScript职能分离(并不是说代码不能写在一起)

  • HTML/CSS/JS各司其职
  • 应当避免不必要的由JS直接操作样式
  • 可以用class来表示状态
  • 纯展示类交互寻求零JS方案

2. 组件封装

好的UI组件具备正确性、扩展性、复用性

2.1. 基本方法

  • 结构设计
  • 展现效果
  • 行为设计
    • API(功能)
    • Event(控制流,使用自定义事件解耦)

轮播图示例: image.png

2.2. 改进:插件化

  • 将控制元素抽取成插件
  • 插件与组件之间通过依赖注入方式建立联系

image.png

class Slider{
    constructor(id, ...args){
        // ...
    }
    
    // ...
    
    registerPlugins(...plugins){
        plugins.forEach(plugin => plugin(this))
    }
}

const slider = new Slider('xxx');
// 定义好功能,需要时以插件形式注入
slider.registerPlugins(pluginController, pluginNext, pluginPrevious);

2.3. 改进:模板化

  • 将HTML模板化,更易于扩展,做到数据驱动

image.png

2.4. 改进:抽象化(组件框架)

image.png

// 通过继承实现
class Slider extends Component{
    constructor(...args){
        // ...
    }
    registerPlugins(...plugins){
        // ...
    }
    render(data){
        // ...
    }
}

2.5. 更多改进

  • 考虑嵌套的情况,比如子组件作为父组件的插件
  • CSS的模板化(可考虑css in js方案)

3. 过程抽象

用来处理局部细节控制的一些方法

应用函数式编程思想

过程抽象:为了能够让“只执行一次”的需求覆盖不同的事件处理,将这个需求剥离出来的过程

// 高阶函数
function once(fn){
    return function (...args){
        if(fn){
            const result = fn.apply(this, args);
            fn = null;
            return result;
        }
    }
}

const test = once(() => {
    console.log('bar');
})
test();  // bar(只输出一次)
test();
test();

声明式与命令式

image.png

image.png

// 一.、命令式
if(xxx){
    fn1()
} else if(yyy){
    fn2()
} else if(zzz){
    fn3()
} else {
    // ...
}

// 二、声明式(扩展性比上面的命令式更好)
function toggle(...action){
    return function(...args){
        // 相当于循环执行actions中的函数
        let action = action.shift();
        actions.push(action);
        return action.apply(this, args);
    }
}

toggle(
    fn1,
    fn2,
    fn3,
    ...
)