npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

overload-in-js

v0.3.0

Published

Overload in javascript

Downloads

6

Readme

在JavaScript中使用重载

Version 0.3.0


引入

    // mjs 引入
    import { overload } from 'overload-in-js';
    // cjs 引入
    const { overload } = require('overload-in-js');

如何使用

基础功能

  overload(f): overload; // 无参函数重载
  overload(types..., f): overload; // 有参函数重载
  overload(): polymerization; // 最终生成聚合函数

  overload需要输入一组类型名称,它们分别对应重载函数形参列表,类型名指定后要在末尾设置重载函数。一组重载定义完成后可以接着后面定义新的一组重载,格式也完全一样。当所有的重载都定义完成时需要不传任何值执行一次,该过程会生成一个聚合函数,当我们调用聚合函数时会根据输入参数的类型自动匹配运行其内部的重载函数。

    import { overload } from 'overload-in-js';

    const add = overload('number', 'number', function(a, b) {
        return a + b;
    })('string', 'string', function(a, b) {
        return Number(a) + Number(b);
    })();

    add(1, 2); // 3
    add('1', '2'); // 3

  如果我们在指定参数类型时需要用到自定义对象,您可以像下面这样进行定义。

    import { overload } from 'overload-in-js';

    function PNumber(value) {
        this.value = value
    } // 用class定义也可以。

    const add = overload(PNumber, PNumber, function(a, b) {
        return a.value + b.value;
    })();

    add(new PNumber(1), new PNumber(2)); // 3

  需要注意的是有时候我们很容易将Number、String这样函数误当成类型直接传入,请使用'number', 'string' 等样式字符串来指定基本数据类型,您也可以参考文档最后的类型表。

使用 autoLength 钩子

  上面这些可以明确知道每种类型参数的个数,这种类型的重载我称它匹配重载。有时候一些参数可能不固定,面对这种情况我们将使用autoLength来包装参数类型此时重载就变成了通项重载。只要参数列表中有一个使用了autoLength包装,那么这一条重载都将变为通项重载。

    import { overload, autoLength } from 'overload-in-js';

    // 纯数字
    const add = overload(autoLength('number'), function(...values) {
        return values.reduce((total, v) => total + v, 0);
    })
    // 字符串 + 数字
    (autoLength('string'), autoLength('number'), function(...values) {
        return values.reduce((pre, v) => pre + v, '');
    })
    // 数字 + 字符串。这是一次指定多个类型的写法
    (autoLength('number', 'string'), function(...values) {
        return values.reduce((pre, v) => pre + Number(v), 0);
    })();

    add(1, 2, 3, 4); // 10
    add('1', '2', 3, 4); // '1234'
    add(6, 7, '5'); // 18

注意: autoLength仅用于重载定义阶段,执行阶段直接使用会报错。同时请勿滥用通项重载,复杂的通项重载会让代码辨识度降低造成逻辑混乱导致重载覆盖。

使用 typeNone 钩子

  假设存在这种情况,可执行函数形参是一个可选参数,如果我们仅传入一个值,如下。

    import { overload } from 'overload-in-js';
    const add = overload('number', 'number', (a = 0, b = 1) => a + b)();

    add(1); // error

  那么毫无疑问执行聚合函数的时候会报错。但我们又希望在传入一个值的时候触发该函数,该怎么解决呢?typeNone钩子就用于解决这一问题,它就像一个带有类型的undefined,仅用于匹配形参类型但不表示任何值。使用方式如下。

    import { overload, typeNone } from 'overload-in-js';
    const add = overload('number', 'number', (a = 0, b = 1) => a + b)();

    add(typeNone('number'), 5); // 0 + 5 = 5
    add(3, typeNone('number')); // 3 + 1 = 4
    add(typeNone('number'), typeNone('number')); // 0 + 1 = 1

注意: typeNone仅用于聚合函数执行阶段,在重载定义阶段直接使用则会报错。

细节

  匹配重载即每一个类型都匹配上才会执行相应的重载函数。而通项重载则是一个不确定长度的重载,一定范围内只要输入的参数类型不发生改变那么就会匹配,当所有条件满足的时候执行相应的重载函数。

  当我们调用聚合函数的时候,overload会优先按照匹配重载的规则寻找符合条件的函数并执行。如果没有找到就会按照通项重载的规则查找相应的重载函数并执行。如果前两个都没有找到就会报错。

  通过上面的解释我们会发现优先级:匹配重载 > 通项重载。没错,所以我们在通过它们进行编码时应当注意如果可以确定每个参数长度的尽量用匹配重载,不当的使用通项重载会产生冗余的运算。

  当然有一种情形除外,如果我们输入的参数个数大于所有匹配重载最长的参数个数,那么overload会直接按照通项重载来寻找重载函数。

如果不知道类型怎么办?

  一些基础类型您可以使用typeof来查询它们。如果是对象类型您需要直接传入它们的构造函数。下面是一些常见的参数类型列表。

| 类型 | 输入 | 样本 | | :------------- | ---------- | -----------------------------------: | | null | null | null | | undefined | void 0 | undefined | | bool | 'boolean' | true,false | | number | 'number' | 1,NaN,Infinity | | string | 'string' | '1' | | function | 'function' | Number,String, function f() {} | | generator | 'function' | function* g() {} | | async function | 'function' | async function af() {} | | symbol | 'symbol' | Symbol(1) | | bigint | 'bigint' | 1n | | array | Array | [1,2,3],new Array() | | RegExp | RegExp | /^[123].txt$/ | | Object | Object | {} | | Promise | Promise | new Promise() |