第六届字节跳动青训营第四课 | 青训营

54 阅读3分钟

如何写好JavaScript

什么才是好的JavaScript代码

1690884484536

写好JS的一些原则

  • 各司其责:HTML、CSS和JavaScript分离
  • 组件封装:更多是与UI打交道,所有封装很重要
  • 过程抽象:在处理UI交互的细节的时候,需要对数据抽象,过程抽象,让代码拥有扩展的能力,更加通用

深夜食堂

怎么样去切换样式

版本一

const btn = document.getElementById('modeBtn');
btn.addEventListener('click',(e)=>{
    const body = document.body;
    if(e.target.innerHTML ==='☀'){
        body.style.backgroundColor = 'black';
        body.style.color = 'white';
        e.target.innerHTML = '🌙';
    }else{
        body.style.backgroundColor = 'white';
        body.style.color = 'black';
        e.target.innerHTML = '☀';
    }
});

版本二

const btn = document.getElementById('modeBtn');
btn.addEventListener('click',(e)=>{
    const body= document.body;
    if(body.classNmae !== 'night'){
        body.className = 'night';
    }else{
        body.className = '';
    }
});

以上版本一代码有什么问题呢?

如果来优化,该怎么做呢?

  • 用javascript来替代了css
  • 若想改动颜色,则会改动js代码,版本二代码就不会改动
  • 在团队里,希望看到第二个代码的

版本二比起上一版本好在哪里

  • 各司其责

结论

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

组件封装

例子:用原生JS写一个电脑网站的轮播图,应该怎么实现?

结构

  • 轮播图是一个典型的列表结构,我们可以用无序列表ul元素来实现
.slider{
    position:relative;
    width:400px;
    height:300px;
}
​
.slider-picture{
    position:relative;
    list-style-type: none;
}
​
.one,.noe-item{
    position:absolute;
    transition: opacity 1s;
    opacity: 0;/*设置透明度 */
}
​
img{
    width:400px;
    height:300px;
}
​
.one:first-child {
    opacity: 1;
}
​
.one-item{
    list-style-type: none;
    position:absolute;
    transition: opacity 1s;
    opacity:1;
}
window.onload = () =>  {
    let itemList = document.getElementsByClassName('one')
    let index = 0
    setInterval(() => {
        itemList[index].style.opacity = 0
        index = (index + 1) % itemList.length
        itemList[index].style.opacity = 1
    }, 2000)
    // for (let item of itemList) {
    // } 4 % 2 [1, 2, 3]
}

表现

  • 使用CSS绝对定位将图片重叠在同一个位置
  • 轮播图切换的状态使用修饰符(modifier)
  • 轮播图的切换动画使用CSS transition

行为:API

  • Slider

+getSelectedItem()

当前选中的图片元素

+getSelectedItemIndex()

当前选中的图片元素在这个列表的下标

+Slide To()

会SildeTo到某个特定的index的元素上

+SlideNext()

轮播下一张图片

+SlidePrevious()

轮播上一张图片

总结

  • 组件设计的原则:封装性、正确性、扩展性、复用性
  • 实现组件的步骤:结构设计、展现效果、行为设计
  • 三次重构:插件化、模板化、抽象化(组件框架)

javascript编码原则之过程抽象

过程抽象

  • 用来处理局部细节控制的一些方法
  • 函数式编程思想的基础应用

react中应用过程抽象比较多的就是hooks

高阶函数

once

  • 为了能够让只执行依次的需求覆盖不同的事件处理,我们可以将这个需求剥离出来,这个过程我们称为过程抽象
function once(fn){}
return function(...args){
    if(fn){
        const ret = fn.apply(this.args);
        fn = null;
        return ret;
    }
}

HOF

  • 以函数作为参数
  • 以函数作为返回值
  • 常用于作为函数装饰器
  • once
  • Throttle

image-20230819004536615

  • Debounce

跟随鼠标,但是是在停止之后再跟随的

  • Consumer/2

每隔一个时间,再去调用function的

  • Iteratlive

会返回一个新的函数

思考和讨论

  • 为什么要使用高阶函数?
  • 什么是纯函数?(eg: add()函数)

得出来的值不可能会有其他值,是确定的。而非纯函数,每次得出的结果都是不一样的

编程范式

命令式

let list = [1,2,3,4];
let mapl = [];
for(let i = 0; i < list.length; i++){
    mapl.push(list[i]*2);
}

声明式

let list = [1,2,3,4];
const double = x => x * 2;
list.map(double);

声明式的写法天然的比命令式可扩展性

总结

  • 过程抽象/HOF/装饰器
  • 命令式/声明式

javascript代码质量优化之路

交通灯状态切换

  • 实现一个切换多个交通灯状态切换的功能

感受

学习这四节课,让我清楚的知道了实际操作的重要性,不光要听,最主要的是自己会,很多时候,听完了再去操作会发现自己又不会了,而且无从下手