原文地址:https://segmentfault.com/a/1190000006051586?utm_source=tuicool&utm_medium=referral 本处仅仅个人存档学习,如有侵权,请联系我删除。 Functor
仿函数(Functor)是 C++ 里面一个重要的概念,简而言之就是使用重载了 operator() 运算符的对象模仿函数的行为,带来的收益是仿函数可以携带自身状态,普通的 C++ 函数不是对象,做不到这一点。 js 中的函数本身就是对象,可以携带自身状态,另外还有 curry 化等函数式编程的方法让函数缓存状态,基本上没有仿函数存在的必要。最简单的你可以这样写: function foobar() {
    return foobar.a;
} foobar.a = ;
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(); 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'
最后,这只是个脑洞!每个语言都有自身的规律和方法论。不要真的在项目里这么写,除非你的项目目的就是创造漂亮的语法。  

js Functor Copy的更多相关文章

  1. (网页)Angular.js 中 copy 赋值与 = 赋值 区别

    转自st.gg Angular.js 中 copy 赋值与 = 赋值 区别 为什么用 $scope.user = $scope.master; $scope.master 会跟着 $scope.use ...

  2. js & auto copy

    js & auto copy https://developer.mozilla.org/zh-CN/docs/Web/Events/copy Ctrl + C Command + C doc ...

  3. js & click copy to clipboard

    js & click copy to clipboard https://www.cnblogs.com/xgqfrms/p/9999061.html https://www.cnblogs. ...

  4. js clear copy

    js clear copy window.getSelection().empty() & window.getSelection().removeAllRanges() & docu ...

  5. js深浅copy

    ...点copy是浅拷贝var obj1 = [1,{a: 1}];//var obj2 = Object.assign( {}, obj1);//浅copy//var obj2 = JSON.par ...

  6. js 对象 copy 对象

    function clone(myObj) { if (typeof (myObj) != 'object') return myObj; if (myObj == null) return myOb ...

  7. js array copy method

    //浅拷贝: let arr=[1,2,3,4] let arr2=arr arr[3]=0 console.log(arr,arr2) //output: (4) [1, 2, 3, 0] (4) ...

  8. JS 点击复制Copy (share)

    分享自:http://www.cnblogs.com/athens/archive/2013/01/16/2862981.html 1.实现点击按钮,复制文本框中的的内容 1 <script t ...

  9. js copy

    Javascript 实现复制(Copy)动作方法大全 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014-06-20我要评论 现在浏览器种类也越来越多,诸如 IE.Firefo ...

随机推荐

  1. 数据库管理哪家强?Devart VS Navicat 360°全方位对比解析

    今天小编向大家推荐的是两个开发环节的主流数据库管理品牌,那么你知道这两款数据库管理软件品牌与数据库引擎配套的管理软件有什么区别吗?小编这就360°全方位为您解答: ★ 品牌介绍 Devart:拥有超过 ...

  2. day_14 匿名函数与内置函数连用 作业题

    ''' 要求: 从文件中取出每一条记录放入列表中,列表的每个元素都是` {'name':'egon','sex':'male','age':18,'salary':3000}`的形式 ''' all_ ...

  3. python导入不同目录下的自定义模块

    一.代码目录结构 自定义的模块在Common包下,Study文件下SelectionSort.py文件导入自定义的模块 二.源码 2.1:SelectionSort.py文件   python导包默认 ...

  4. vscode匹配括号插件

    给大家推荐一个vscode匹配括号的插件: Bracket Pair Colorizer.超级好用哦

  5. oracle 7.4安装nvidia驱动

    2019-8-28 参考网页: 如何在k8s集群中安装nvidia.cuda并使用GPU进行训练 https://blog.csdn.net/u013042928/article/details/78 ...

  6. PCL智能指针疑云 <一>

    背景: 最近写了一个包,使用ndt算法拼接点云,构建三维壁面环境的点云地图. 设计一个lidar类,表征激光雷达.可以获取点云数据并存储到容器 std::vector<PointCloudPtr ...

  7. Android字体设置,Roboto字体使用

    一.自定义字体 1.android Typeface使用TTF字体文件设置字体 我们可以在程序中放入ttf字体文件,在程序中使用Typeface设置字体.第一步,在assets目录下新建fonts目录 ...

  8. SQL语法——Join详解

    一.INNER JOIN 用法: select column_name(s) from table 1 INNER JOIN table 2 ON table 1.column_name=table ...

  9. Java数据结构之排序---快速排序

    快速排序是对冒泡排序的一种改进. 快速排序的基本思想: 假设我们以升序为例,它的执行流程可以概括为,每一趟选择当前所有子序列中的一个关键字(通常我们选择第一个,下述代码实现选择的也是第一个数)作为枢纽 ...

  10. [CSP-S模拟测试]:括号密码(贪心)

    题目描述 在“无限神机”的核心上,有一个奇怪的括号密码,密码初始已经有一个括号序列,有$n$个限制条件,每个限制条件描述为$l_i$和$r_i$,表示区间$[l_i,r_i]$的括号序列必须合法.调整 ...