跟着月影学Javascript|青训营笔记

125 阅读3分钟

跟着月影学Javascript|青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第3天

写好JS的一些原则

  1. 各司其职:让HTML,CSS,Javascript职能分离
  2. 组件封装:好的UI组件具备正确性,扩展性,复用性
  3. 过程抽象:应用函数式编程思想

如何实现各司其职

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

什么是组件

组件是指Web页面上抽出来一个个包含模板(HTML),功能(JS)和样式(CSS)的单元。好的组件具备封装性,正确性,扩展性,复用性。

如何实现组件封装

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

什么是过程抽象

过程抽象

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

image.png

高阶函数

为了能够让“只执行一次“的需求覆盖不同的事件处理,我们可以将这个需求剥离出来。这个过程我们称为过程抽象
eg.下面的Once就是高阶函数
三次调用foo函数但是只有第一次函数有返回值,因为函数第一次执行后函数就被设置为了null,所以只能调用一次

function once(fn) { 
    return function(...args) {
        if(fn) {
            const ret = fn.apply(this, args); 
            fn = null;
            return ret; 
            } 
         } 
     }
     const foo = once(() => { console.log('bar'); }); 
     foo();
     foo();
     foo();

常用高阶函数

Throttle节流函数
使传入的函数经过一段时间执行一次

function throttle(fn, time = 500) {
     let timer;
     return function(...args) {
         if(timer == null) {
             fn.apply(this, args);
             timer = seTimeout(() => {
                 timer = null;
             }, time)
         }
     }
 }

Debounce防抖函数
不会马上调用函数会等待一定时间才会触发函数

function debounce(fn, dur) {
    dur = dur || 100;
    var timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, arguments);
        }, dur);
    }
}

Consumer

可以不断调用某个函数,但是只会定时每隔一段时间执行一次

function consumer(fn, time) {
    let tasks = [],
    timer;
    return function(...args) {
        tasks.push(fn.bind(this, ...args));
        if(timer == null) {
            timer = setInterval(() => {
                tasks.shift().call(this)
                if(tasks.length <=0) {
                clearInterval(timer);
                timer = null;
                }
           },time)
        }
    }
}

Iterative可迭代方法

    function iterative(fn) {
        return function(subject, ...rest) {
            if(isIterable(subject)) {
                const ret = [];
                for(let obj of subject) {
                    ret.push(fn.apply(this, [obj, ...rest]));}
                    return ret;
            }
            return fn.apply(this, [subject, ...rest]);
        }
    }
    

编程范式

命令式和声明式
命令式:告诉编译器该做什么。即就告诉编辑器如何做
声明式:告诉编译器做什么。如何做的部分,将被抽象到高阶函数中。 image.png 命令式

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);

函数式编程的优点

纯函数 大多数函数式编程的好处来自编写纯函数。

定义: 对给定的输入返回相同的输出的函数。

eg:

function getSum(n1,n2){
  return n1+n2
}

这是一个简单的纯函数,我们给它一个输入,它返回相同的输出。 可见,纯函数遵循”引用透明性“。

同时,纯函数不应该改变任何外部环境变量,即纯函数不依赖任何外部变量。