javascript 函數 add(1)(2)(3)(4)實現無限極累加 —— 一步一步原理解析


問題:我們有一個需求,用js 實現一個無限極累加的函數, 形如 add(1) //=> 1; add(1)(2)  //=> 2; add(1)(2)(3) //=>  6; add(1)(2)(3)(4) //=> 10; 以此類推。。。。。

乍一看很神奇, 下面我將一步一步實現一個這樣的 add()函數。


第一步首先,  我們要了解一個知識點: 函數的 toString()方法當我們直接alert() 一個函數的時候會被調用(或者 用 console.log() 打印一個函數的時候會被調用)。

舉一個例子:

function s(a){
    return  a+1;
}
alert(s);

  

第二步:好的,我們現在對函數 s 定義一個 toSting() 方法

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

  

定義了s.toString 方法后, 直接console.log(s) 的話,會打印出這個函數, 如果直接 alert(s)的話,我們可以看到會彈出 “2”, 我們檢測一下s 的類型(typeof(s)),

顯然 s 是一個函數。

第三步:好的,現在我們來給這個  s  函數包裹上一層"外套"  -:)

function add(a){
 function s(a){
    return  a+1;
 }
 s.toString = function(){return a;}
 return s;
}
console.log(add(3));
 

  

在上面的代碼中,我們給之前的代碼 包裹了一層,並且也修改了一下s.toSting() 方法,讓它返回的是外面傳遞進來的參數a, 而不是之前固定的2。
包裹了一層后,返回值為一個函數,這樣就形成了一個閉包。 這樣,我們在調用 add(3) 的時候,返回值其實是一個函數, 里面的 s 這個函數。

但是,當我們 alert(s(3)) 的時候, 會彈出  3 。

第四步:好的,下面是最后一步,“見證奇跡的時刻到了”————

function add(a){
 function s(b){
    a =   a+b;
    return s;
 }
 s.toString = function(){return a;}
 return s;
}
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 函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM