js中实现单分派泛函数

栏目: JavaScript · 发布时间: 5年前

内容简介:有这样一个函数,我们根据传入的第一个参数类型不同,以不同方式执行相同操作(单分派泛函数), 我们来看一个简单的例子:这个例子比较简单,每一个我们先来看看使用方式:

有这样一个函数,我们根据传入的第一个参数类型不同,以不同方式执行相同操作(单分派泛函数), 我们来看一个简单的例子:

function show(value) {
    if(value instanceof Array) {
        console.log(value.join('-'));
    } else if(value instanceof Date) {
        console.log(value * 1);
    } else if (value instanceof Number || value instanceof Boolean) {
        console.log(value * value)
    } else {
        console.log(value);
    }
}
复制代码

这个例子比较简单,每一个 if 后面只有一行代码,然而在实际工作中,也许每一个 if 后面都有一段逻辑复杂逻辑复杂的代码,我们通常的处理方式就是将其拆分出来作为一个新的函数,然后在 if 里面调用,现在我向大家介绍一种新的方法来出来这种情况。

我们先来看看使用方式:

const show = singledispatch(vlaue => console.log(value));
show
    .dispatch(value => console.log(value * value))
    .register(Number)
    .register(Boolean);
    .dispatch(value => console.log(value * 1))
    .register(Date);
    .dispatch(value => console.log(value.join('-')))
    .register(Array);

show(2); // 4
show(true); // 1
show([3, 4, 5]) // 3-4-5
show(new Date()) // 1542177163659
show({a: 1}) // [object Object] 
复制代码

singledispatch 接受一个函数,返回一个函数对象 showshow 先dispatch一个函数,之后注册一个Number和Boolean,表示 show 传入的参数如果是数字或者布尔类型,就调用dispatch的这个函数,之后也是这样。

singledispatch 需要返回一个函数对象,我们假设叫 out ,这个函数对象有两个方法分别为 dispatchregister ,链式调用就需要返回 out ;具体实现过程如下,

function singledispatch(fn /* 默认是一个空函数*/ = Function.prototype) {
    let current; // 用于记录啊dispatch的函数
    let registry = {}; // 一个对象,用于存储某个类型下对应调用的函数
    function out(arg){
        let type = Object.prototype.toString.call(arg);
        if(registry[type]) {
            return registry[type](arg);
        } else {
            return fn(arg);
        }
    }

    out.dispatch = function dispatch(f) {
        if(typeof f !== 'function') {
            throw Error('some error')
        }
        current = f;
        return out;
    }

    out.register = function register(ctor) {
        if(!current) {
            throw Error('register必须在dispatch之后调用')
        }
        registry[`[object ${ctor.name}]`] = current;
        return out
    }

    return out;
}
复制代码

有的时候,我们并不是根据类型做判断,我们希望可以自定义的方式去判断,因此,register可以传入一个函数,用这个函数去做判断,就像下面这个样子:

const f = singledispatch();

f
    .dispatch(v => v * v * v).register(v => v > 10)
    .dispatch(v => v * v).register(v => v <= 10);

f(11) // 1331
f(5) // 25

复制代码

此时的 singledispatch 需要修改 registerout

function singledispatch(fn = Function.prototype) {
    let current;
    let registry = [];
    let conditions = []
    function out(arg){
        let index = conditions.findIndex(f => f(arg));
        if(index >= 0) {
            return registry[index](arg);
        } else {
            return fn(arg);
        }
    }

    out.dispatch = function dispatch(f) {
        if(typeof f !== 'function') {
            throw Error('some error')
        }
        current = f;
        return out;
    }

    out.register = function register(condition) {
        if(!current) {
            throw Error('register必须在dispatch之后调用')
        }
        if(typeof condition !== 'function') {
            throw Error('some error')
        }
        conditions.push(condition);
        registry.push(current);
        return out
    }

    return out;
}
复制代码

以上所述就是小编给大家介绍的《js中实现单分派泛函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

R for Data Science

R for Data Science

Hadley Wickham、Garrett Grolemund / O'Reilly Media / 2016-12-25 / USD 39.99

http://r4ds.had.co.nz/一起来看看 《R for Data Science》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码