资讯专栏INFORMATION COLUMN

学习add(1)(2)(3)

yacheng / 2462人阅读

摘要:实现什么是柯里化又称部分求值,简单来说就是只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。你可以这样正规写当然用柯里化也可以这样定义一个函数,接受一个参数并返回一个新的函数。

实现add(1)(2)(3) 什么是柯里化(Currying)

又称部分求值(Partial Evaluation),简单来说就是只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

你可以这样正规写

var sum = function (a, b) {
    return a + b;
}

当然用柯里化也可以这样

var sumCurrying = function(a) {
    return function(b) {
        return a + b;
    }
}

var first = sum(1); //function
var second = sum(2); //function

sumCurrying(1)(2); //3
first(3); //4
second(4); //6

定义一个sumCurrying函数,接受一个参数并返回一个新的函数。调用sumCurrying函数之后,返回的函数就通过闭包的方式记住了sumCurrying的第一个参数。

但是这里只能接受两个参数,如果能接受很多个参数怎么办呢?

柯里化的运用
function add () {
    var args = [].slice.call(arguments);

    var fn = function () {
        var arg_fn = [].slice.call(arguments);
        return add.apply(null, args.concat(arg_fn));
    }

    fn.valueOf = function() {
        return args.reduce((a, b) => a + b);
    }
    return fn;
}

我第一次看这个代码的时候我也是纳闷,what the fuck??valueOf是什么鬼?它运行了吗?看了原博主的我才明白了原来valueOf和toString在某些时候是会自己调用的,还牵扯到了类型转换,啊啊啊啊~。

来看看这个类型转换的题

2 == [[[2]]] //是真还是假?

解析:

引用类型转换为基本类型(所有的引用类型转换为布尔值都是true)

引用类型转换为字符串

1.优先调用toString方法(如果有),看其返回结果是否是原始类型,如果是,转化为字符串,返回。
2.否则,调用valueOf方法(如果有),看其返回结果是否是原始类型,如果是,转化为字符串,返回。
3.其他报错。

引用类型转化为数字

1.优先调用valueOf方法(如果有),看其返回结果是否是原始类型,如果是,转化为数字,返回。
2.否则,调用toString方法(如果有),看其返回结果是否是原始类型,如果是,转化为数字,返回。
3.其他报错。

以下来自犀牛书:

1,null和undefined,相等。
2,数字和字符串,转化为数字再比较。
3,如果有true或false,转换为1或0,再比较。
4,如果有引用类型,优先调用valueOf。
5,其余都不相等。

回到类型转换的这个题,因为是与数字进行比较,所以先调用valueOf(),返回的是本身不是原始类型,然后调用toString()得到"2",然后变成了字符串和数字("2" == 2)进行比较。

所以结果为 true

好,回到valueOf和toString被自动调用的问题上。

var obj = {name: "Coco"};
var str = "123" + obj; 
console.log(str); //123[object Object]

为什么会这样呢?上面的例子实际上是

var obj = {name: "Coco"};
var str = "123" + obj.toString();

当然我们可以改写toString和valueOf方法

如果只改写 valueOf() 或是 toString()其中一个,会优先调用被改写了的方法,而如果两个同时改写,则会像 Number 类型转换规则一样,优先查询 valueOf() 方法,在 valueOf() 方法返回的是非原始类型的情况下再查询 toString() 方法。

var obj = {
    toString: function () {
        console.log("调用了toString");
        reutrn "1";
    },
    valueOf: function () {
        console.log("调用了vlaueOf");
        return "100";
    }
}

alert(obj + "1"); 
//调用了valueOf 
//"1001"

对于函数的valueOf来说:

function test () {
    var a = 1; 
    console.log(a);
}

test; 
//重新打印了一遍test函数体,其实是自行调用调用了test.valueOf()
//如果valueOf返回的不是原始类型,那么就会尝试去找toString方法。

所以add(1)(2)

首先进入add

然后进入fn

然后进入add

调用valueOf

3

参考资料:
一道面试题引发的javascript类型的转换的思考

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86816.html

相关文章

  • java-list-map-set 学习记录

    摘要:集合类类型解释的父类集集合中的元素不按特定方式排序,并且没有重复对象。他的有些实现类能对集合中的键对象进行排序。 集合类 2017-07-10 22:24:57 blog site https://github.com/Fiz1994 类型解释: Collection : Set,List 的父类 Set(集):集合中的元素不按特定方式排序,并且没有重复对象。他的有些实现类能对集合中的...

    stackvoid 评论0 收藏0
  • tensorflow

    当谈到深度学习和人工智能时,TensorFlow是最受欢迎的框架之一。TensorFlow是一个开源的机器学习框架,由Google开发和维护。它允许开发人员和研究人员使用Python等编程语言来构建和训练深度学习模型。在本文中,我们将探讨TensorFlow的编程技术。 1. 安装TensorFlow 首先,您需要安装TensorFlow。TensorFlow可以通过pip包管理器轻松安装。在...

    CompileYouth 评论0 收藏1271
  • 如何把yolov5里的PANet层改成BiFPN详析

      如今yolov5的neck用的都是PANet,在efficient文章中给出了BiFPN结构,也有更为很不错的特性,接下来本文关键为大家介绍了对于如何将yolov5里的PANet层改成BiFPN的资料,需用的小伙伴可以借鉴一下  一、Add  1.在common.py后放入如下所示编码   #融合BiFPN设定可学习培训主要参数学习培训不一样支系的权重值   #2个支系add实际操作   cl...

    89542767 评论0 收藏0

发表评论

0条评论

yacheng

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<