前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何写好JavaScript

如何写好JavaScript

作者头像
用户6256742
发布2022-07-06 14:31:29
4550
发布2022-07-06 14:31:29
举报
文章被收录于专栏:网络日志网络日志

写好JavaScript的三个原则:各司其责 组件封装 过程抽象

各司其责

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

组件封装

组件是指Web页面上抽出来的一个个包含模块(HTML)、样式(CSS)和功能(JS)的单元。好的组件具备封装性、正确性、扩展性、复用性。实现组件的步骤:结构设计、展现效果、行为设计,三次重构:插件化重构、模板化重构、抽象化重构。

  • 结构设计:HTML
  • 展现效果:CSS
  • 行为设计:JS
    • API(功能),API 设计应保证原子操作,职责单一,满足灵活性。
    • Event(控制流),使用自定义事件来解耦。
  • 插件化重构,即解耦
    • 将控制元素抽取成插件
    • 插件与组件之间通过依赖注入方式建立联系
  • 模板化重构
    • 将HTML模板化,更易于扩展
  • 抽象化重构(组件框架)
    • 将通用的组件模型抽象出来

过程抽象

过程抽象是指用来处理局部细节控制的一些方法,是函数式编程思想的基础应用。

  • 高阶函数
    • 以函数作为参数
    • 以函数作为返回值
    • 常用于函数装饰器
代码语言:javascript
复制
//零阶高阶函数,等价于直接调用函数
function HOF_0 (fn){
    return function(...args){
        return fn.apply(this.args);
    }
}
  • 构造 once 高阶函数,为了能够让“只执行一次”的需求(例如一些异步操作、一次性的HTTP请求)覆盖不同的事件处理,我们可以将这个需求利用闭包剥离出来。这个过程称为过程抽象。
代码语言:javascript
复制
function once ( fn ) {
    return function (...args){
        const res = fn.allpy (this.args);
        fn = null;
        return res;
    }
}

防抖函数,在第一次触发事件时,不立即执行函数,而是给出一个期限值,如果在期限值内没有再次触发滚动事件,那么就执行函数,如果在期限值内再次触发滚动事件,那么当前的计时取消,重新开始计时

节流函数,类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活。效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。

为什么要使用高阶函数?

写好 JavaScript

写代码应该关注

  • 效率
  • 风格
  • 使用场景
  • 约定
  • 设计 具体的代码实现要因场景而定,不同的场景注重点不一样,例如在某些比较底层的场景,可能更注重效率,而在多人协作的时候可能更关注约定。

判断是否是4的幂

常规操作

优化版本1,利用 4 的幂的二进制数最高位为1,低位为偶数个0

优化版本2,利用正则表达式

代码语言:javascript
复制
const isPowerOfFour = (num) => {
    num = parseInt(num).toString(2);
    return /^1(?:00)*$/.test(num);
}

实现交通灯切换效果

版本一,利用setTimeout,可能出现回调地狱

优化版本,利用async/await

洗牌算法

错误示例 看似可以正确洗牌,但实际上较小的牌放到前面的概率更大,较大的的牌放到后面的概率更大

正确示例

代码语言:javascript
复制
const cards = [0,1,2,3,4,5,6,7,8,9]; 
function *draw(cards){ 
    const c = [...cards]; 
    for(let i = c.length ; i > 0 ; i--){ 
        const pIdx = Math.floor(Math.random() * i);
        [c[pIdx],c[i - 1]] = [c[i - 1],c[pIdx]]; 
        yield c[i - 1];
    } 
    return c; 
}

分红包问题

版本一,类似于切蛋糕,取最大的继续切分,得出的结果会比较平均

版本二,随机性较大,可能会有较大的红包出现

代码语言:javascript
复制
function *draw(cards){ 
    const c = [...cards]; 
    for(let i = c.length ; i > 0 ; i --){ 
        const pIdx = Math.floor(Math.random()*i); 
        [c[pIdx],c[i-1]] = [c[i - 1],c[pIdx]]; 
        yield c[i-1] 
    } 
    return c;
} 

function generate(amount,count){ 
    if(count <= 1) return [amount]; 
    const cards = Array(amount - 1).fill(null).map((_,i) => i+1); 
    const pick = draw(cards); 
    const result = []; 
    for(let i = 0 ; i < count; i++){ 
        result.push(pick.next().value);
    } 
    result.sort((a,b)=>a-b); 
    for(let i = count - 1 ; i > 0 ; i--){ 
        result[i] = result[i] - result[i - 1];
    } 
    return result; 
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写好JavaScript的三个原则:各司其责 组件封装 过程抽象
    • 各司其责
      • 组件封装
        • 过程抽象
        • 写好 JavaScript
          • 写代码应该关注
            • 判断是否是4的幂
              • 实现交通灯切换效果
                • 洗牌算法
                  • 分红包问题
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档