如何写好 JavaScript| 青训营

64 阅读3分钟

JavaScript 编码原则之各司其责

  • HTML、CSS、JavaScript职能分离
  • UI组件封装,具备正确性、扩展性、复用性
  • 过程抽象,函数式编程

职能分离

案例1-修改黑夜模式

image-20230802130252849

方案1. 直接操作dom修改css样式

方案2. 添加黑夜css样式,点击触发修改属性(className)

方便修改,变化不大,减少DOM操作,推荐方案2

方案3. 只用css,把label添加for属性指向checkbox,checkbox添加伪元素:checked,编写checked样式

应当避免不必要的JS直接操作样式

可以用class表示状态

展示类交互寻求零JS方案

组件封装

组件设计的原则:封装性、正确性、扩展性、复用性

实现组件的步骤:结构设计、展现效果、行为设计

案例2-轮播图

轮播图整体结构是无序列表,使用css绝对定位将图片重叠同一个位置,切换状态使用,切换动画使用CSS transition

image-20230802130501669

封装函数

getSelectedItem() 获取选择图

getSelectedItemIndex() 获取选择图地址

slideTo() 轮播到第几张图

slideNext() 轮播下一张图

slidePrevious() 轮播上一张图

用定时器setInterval执行slideNext()

添加控制流(圆点、箭头控制图片位置,关联index)

重构插件化

  • 封装函数,导入时控制函数就行。

重构模板化

  • 在js中编写html部分,更易于扩展。

抽象(组件框架)

  • 将组件通用模型抽象出来。

过程抽象

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

函数式编程思想的基础应用

HOF以函数作为参数,以函数作为返回值,常用于函数装饰。

常用高阶函数

  • Once 只执行一次
function once(fn){
	return function(...args){
		if(fn){
			const ret = fn.apply(this,args);
			fn = null;
			return ret;
		}
	}
}
  • Throttle 节流函数

节流就是连续触发事件,在指定时间间隔内只会执行一次函数,节流会减少函数的执行频率。节流的应用:图片懒加载。

function throttle(fn,delay=500){
	let timer;
	return functions(...args){
		if(timer==null){
			fn.apply(this,args);
			timer=setTimeout(()=>{
				timer=null;
			},delay)
		}
	}
}
  • Debounce防抖函数

防抖就是触发事件后n秒后才执行事件处理函数,如果在n秒内又触发了事件,就会重新计时。防抖的应用:搜索联想。

function debounce(fn, delay = 500) {
  let timer = null;
  return function(...args) {
    if (timer !== null) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  };
}

编程范式 命令式与声明式

  • 命令式 主过程,强调怎么做
  • 声明式 主结果,强调做什么
let list = [1,2,3,4];
//命令式
let map = [];
for(let i = 0; i < list.length ; i ++){
	map.push(list[i]*2);
}
//声明式
const double = x => x*2;
list.map(double);

质量优化

代码实践1 - 交通灯

  • 方法1.定时器内嵌定时器
  • 方法2.定时器循环状态表
  • 方法3.过程抽象,写出交通灯的等待,停止,运行函数
  • 方法4.异步加抽象函数

代码实践2-4的幂

  • 方法1.
ini复制代码var isPowerOfFour = function(n) {
    if(n==0){
        return false
    }
    while(n%4==0){
        n=n/4
    }
    return n==1
};
  • 方法2.
ini复制代码var isPowerOfFour = function(n) {
    return n>0 && (n==1||(n%4==0&&isPowerOfFour(n/4)))
};
  • 方法3.
javascript复制代码var isPowerOfFour = function(n) {
    return n>0 && (n&(n-1))==0 && (n&0xAAAAAAAA)==0
};
  • 方法4.
javascript复制代码var isPowerOfFour = function(n) {
    const nstr = n.toString(2)
    return /^1(00)*$/.test(nstr)
};
  • 方法5.
ini复制代码var isPowerOfFour = function(n) {
    return n>0 && (n&(n-1))==0 && n%3==1
};
  • 方法6.
javascript复制代码var isPowerOfFour = function(n) {
    if(n<=0){
        return false
    }
    let sqrtn = Math.floor(Math.sqrt(n)) 
    return sqrtn*sqrtn==n && (sqrtn&(sqrtn-1))==0
};

代码实践3 - 洗牌

错误写法:random 随机生产数在进行数组排序,统计各个数出现的次数,发现越小的数出现的概率越大。

正确写法:random 随机生产数提出到数组后面,统计各个数出现的次数,发现各个数出现次数概率相似。

代码实践4 - 分红包(每个人不能小于0.01)

  • 方法1.切西瓜法

每次拆最大的那个值,random 随机生产数。

  • 方法2.抽牌法

把金额比作数组,分几份就是几个区间,随机插入。