问题:我们有一个需求,用js 实现一个无限极累加的函数, 形如 add(1) //=> 1; add(1)(2)  //=> 2; add(1)(2)(3) //=>  6; add(1)(2)(3)(4) //=> 10; 以此类推。。。。。

乍一看很神奇, 下面我将一步一步实现一个这样的 add()函数。

第一步:首先,  我们要了解一个知识点: 函数的 toString()方法当我们直接alert() 一个函数的时候会被调用(或者 用 console.log() 打印一个函数的时候会被调用)。

举一个例子:

  1. function s(a){
  2. return a+1;
  3. }
  4. alert(s);

  

第二步:好的,我们现在对函数 s 定义一个 toSting() 方法

  1. function s(a){
  2. return a+1;
  3. }
  4. s.toString = function(){return 2;}
  5. console.log(s);
  6. typeof(s)

  

定义了s.toString 方法后, 直接console.log(s) 的话,会打印出这个函数, 如果直接 alert(s)的话,我们可以看到会弹出 “2”, 我们检测一下s 的类型(typeof(s)),

显然 s 是一个函数。

第三步:好的,现在我们来给这个  s  函数包裹上一层"外套"  -:)

  1. function add(a){
  2. function s(a){
  3. return a+1;
  4. }
  5. s.toString = function(){return a;}
  6. return s;
  7. }
  8. console.log(add(3));

  

在上面的代码中,我们给之前的代码 包裹了一层,并且也修改了一下s.toSting() 方法,让它返回的是外面传递进来的参数a, 而不是之前固定的2。
包裹了一层后,返回值为一个函数,这样就形成了一个闭包。 这样,我们在调用 add(3) 的时候,返回值其实是一个函数, 里面的 s 这个函数。

但是,当我们 alert(s(3)) 的时候, 会弹出  3 。

第四步:好的,下面是最后一步,“见证奇迹的时刻到了”————

  1. function add(a){
  2. function s(b){
  3. a = a+b;
  4. return s;
  5. }
  6. s.toString = function(){return a;}
  7. return s;
  8. }
  9. console.log(add(1)(2)(3)(4));

  

到这里,我们可以看到,上面 console.log(add(1)(2)(3)(4)); 这句话打印出 一个函数,  function 10  , 其实就是当 alert(add(1)(2)(3)(4));的时候,会弹出 10.
这就是 add(1)(2)(3)(4); 的实现过程,显然,我们这个累加函数是可以无限调用的 。-:) 小开心一下哈

下面,我来谈一谈个人的思路和理解,还望大家能踊跃参数, 帮忙指点我一下,不甚感激!

我觉得:整个实现过程就是两个关键点。
1. 使用闭包, 同时要对JavaScript 的作用域链(原型链)有深入的理解;

2. 重写函数的 toSting()方法;

好的,对add(1)(2)(3); 一步一步分析:

a) 执行add(1);

      返回的是里面的  s  函数, 通过闭包,s 函数里面可以访问到 变量 a=1;  所以 当我们 alert(add(1)); 的时候, 调用的 toSting()方法会将作用域(原型链)里面的 a = 1 弹出来。

b) 执行add(1)(2);

      <===等价于===> s(2);  这里面相当于 把 2 传递给 s()函数里面的 b , 让作用域(原型链)里面的 a = a+b ,此时 a = 3, 继续保存在作用域中了。 然后还是返回 s 函数。

c) 执行 add(1)(2)(3);

      <===等价于===> s(3);和上面 b) 中的分析一样,只是更新了作用域中的 a = 6 了,然后同样是返回 s 函数。

javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析的更多相关文章

  1. Javascript函数重载,存在呢—还是存在呢?

    1.What's is 函数重载? );//Here is int 10 print("ten");//Here is string ten } 可以发现在C++中会根据参数的类型 ...

  2. JavaScript语言精粹读书笔记 - JavaScript函数

    JavaScript是披着C族语言外衣的LISP,除了词法上与C族语言相似以外,其他几乎没有相似之处. JavaScript 函数: 函数包含一组语句,他们是JavaScript的基础模块单元,用于代 ...

  3. 深入理解javascript函数系列第一篇——函数概述

    × 目录 [1]定义 [2]返回值 [3]调用 前面的话 函数对任何一门语言来说都是一个核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即 ...

  4. 深入理解javascript函数系列第二篇——函数参数

    × 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...

  5. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

  6. JavaScript函数之美~

    JavaScript函数之美~ 这篇文章,我将就以下几个方面来认识JavaScript中的函数. 函数为什么是对象,如何定义函数? 如何理解函数可以作为值被传递 函数的内部对象.方法以及属性 第一部分 ...

  7. JavaScript 函数参数传递到底是值传递还是引用传递

    tips:这篇文章是听了四脚猫的js课程后查的,深入的理解可以参看两篇博客: JavaScript数据类型--值类型和引用类型 JavaScript数据操作--原始值和引用值的操作本质 在传统的观念里 ...

  8. Javascript函数的简单学习

    第九课函数的定义与调用1:函数的定义    语法格式    function 函数名(数据类型 参数1){//function是定义函数的关键字        方法体;//statements,用于实 ...

  9. 第八章:Javascript函数

    函数是这样一段代码,它只定义一次,但可能被执行或调用任意次.你可能从诸如子例程(subroutine)或者过程(procedure)这些名字里对函数概念有所了解. javascript函数是参数化的: ...

随机推荐

  1. 20150627分享iOS开发笔记

    util是工具的意思:Ad Hoc是特别的,临时的意思;validate是验证的意思: 打包 苹果的键盘真好使 6和6 plus真机测试报错:No architectures to compile f ...

  2. Hibernate 关系映射方式(1)

    来源:本文转载自:http://blog.csdn.net/huangaigang6688/article/details/7761310 Hibernate映射解析——七种映射关系 首先我们了解一个 ...

  3. android全屏和取消全屏 旋转屏幕

    全屏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 取消全屏 getWindow().clearFlags(Win ...

  4. Asp:Cookies应用指南

    实际上,在web开发中,cookie仅仅是一个文本文件,当用户访问站点时,它就被存储在用户使用的计算机上,其中,保存了 一些信息,当用户日后再次访问这个站点时,web可以将这些信息提取出来.    尽 ...

  5. servlet容器开发要点

    v1 是一个http服务器. v2 是一个servlet容器, 可以提供servlet的服务.   =>  动态load servlet字节码,并运行它( 按生命周期). servlet容器它来 ...

  6. 安装MSYS2过程遇到的问题及解决记录

    1.在安装结束后按照官方教程开始更新系统是遇到了如下的错误 could not open file /var/lib/pacman/sync/msys32.db: Unrecognized archi ...

  7. C++ 字符串字面值

    C++ 字符串字面值 C++ 基本字符串类型 C++ 字符串类型 char 和 wchar_t c11 新增了 char16_t 和 char32_t 例子: wchat_t title[] = L& ...

  8. C#之控制台输入和输出

    控制台输出 C# 控制台程序一般使用 .NET Framework Console 类提供的输入/输出服务.Console.WriteLine("Hello World!"); 语 ...

  9. POJ3321/Apple tree/(DFS序+线段树)

    题目链接 Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9692 Accepted: 3217 Descr ...

  10. TcpClient 读写流

    TcpClient 读写流 TcpClient tcp = new TcpClient(); tcp.Connect(IPAddress.Parse("192.168.1.161" ...