开个脑洞,怎样运用 javascript 完成“仿函数”(Functor)?

Functor

仿函数(Functor)是 C++ 内里一个主要的观点,简而言之就是运用重载了 operator() 运算符的对象模拟函数的行动,带来的收益是仿函数能够照顾自身状况,一般的 C++ 函数不是对象,做不到这一点。

js 中的函数自身就是对象,能够照顾自身状况,别的另有 curry 化等函数式编程的要领让函数缓存状况,基础上没有仿函数存在的必要。最简朴的你能够如许写:

function foobar() {
    return foobar.a;
}

foobar.a = 1;
var b = foobar(); // b=>1

如许,foobar 就照顾了自身状况 a,而且能够在函数体重接见 a。

然则这里有一个题目:函数体中 foobar.a 这一句是应用闭包完成的,个中 foobar 这个援用被写死了,从效果上看 foobar 成了一个单例。假如我想要多个 foobar 实例怎样办呢?

以及,我比较喜好 this 指针,而不是闭包。面临这类状况,我更喜好如许的写法:

// 伪代码

function foobar() {
    return this.b;
}

foobar.setB = function (val) {
    this.b = val
}

var foo = new foobar;
foo.setB(1);

var b = foo(); // b=>1

js 完成

那末怎样完成呢?我之前写了一篇文章,内里说 js 不容易完成相似的观点。然则当时我没细想,本日试了一下实在更改一下接口,照样能完成相似效果的。

基础的道理就是如许:

function f() {...}
var functor = f.bind(f);

让一个函数 bind 它本身,如许它不就能用 this 接见本身了吗?然则这里另有个题目,bind 的返回效果并非 f 自身而是另一个函数,functor 的持有者在外部接见不到 f。所以这里还要用 js 的新 api defineProperty 处置惩罚一下,使得对 functor 的某些属性接见,转移到 f 上去。

完全的完成以下:

function makeFunctor(fn, props) {
    function thisFn() {
        return fn.apply(this, Array.prototype.slice.call(arguments));
    }
    
    var ret = thisFn.bind(thisFn);
    
    for (var key in props) {
        if (!props.hasOwnProperty(key)) {
            continue;
        }

        Object.defineProperty(ret, key, {
            configurable : true,
            enumerable : true,
            
            get : function () {
                return thisFn[key];
            },
            
            set : function (value) {
                thisFn[key] = value;
            }
        });
        
        ret[key] = props[key];
    }
    
    return ret;
}

经由过程 makeFunctor,我们能够经由过程一个函数 fn 建立很多个 functor,每一个都有自身的状况,互不影响。而且在 fn 中我们能够运用 this 接见自身状况。比方:

function hello () {
    alert('Hello, ' + this.name);
}

hello.create = function () {
    makeFunctor(hello, {
        name : 'Tom'
    });
}

var ftHello = hello.create();
var ftHello2 = hello.create();

ftHello(); // Hello, Tom'
ftHello.name = 'Jack';
ftHello(); // Hello, Jack'

ftHello2(); // Hello, Tom'

末了,这只是个脑洞!每一个言语都有自身的规律和要领论。不要真的在项目里这么写,除非你的项目目标就是制造美丽的语法。

    原文作者:Y3G
    原文地址: https://segmentfault.com/a/1190000006051586
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞