前端js復(fù)習(xí) 4-函數(shù)

我們的認(rèn)知中函數(shù)是一段可以反復(fù)調(diào)用的代碼塊够傍,函數(shù)還能接受輸入的參數(shù)形娇,不同的參數(shù)會(huì)返回不同的值,在js的世界了里有三種聲明函數(shù)的方法示姿。

  • function命令
  • 函數(shù)表達(dá)式
  • new Function構(gòu)造函數(shù)(幾乎不使用,對(duì)構(gòu)造函數(shù)不理解的可以看js的設(shè)計(jì)模式,后續(xù)會(huì)有章節(jié)介紹)
  • 題外話逊笆,=> 箭頭函數(shù) es6

那我們來(lái)看幾個(gè)列子


//函數(shù)聲明

function test() {
   console.log(1)
}
test() //調(diào)用該函數(shù) 1

//函數(shù)表達(dá)式(匿名函數(shù)賦值給變量)

var test = function() {
    console.log(2)
}栈戳;
test() //2

//如果不是匿名函數(shù)的表達(dá)式,該函數(shù)名只能在函數(shù)里有效难裆,以便在函數(shù)體內(nèi)部調(diào)用自身

var test = function test1() {
     console.log(typeof test1)子檀; // function
};
console.log(test1)乃戈;// error : test1 is not defined

//new Funciton 構(gòu)造函數(shù)(arg1,arg2褂痰,...,函數(shù)內(nèi)容)
var test = new Function(a症虑,console.log(a))
test(1) // 1

//箭頭函數(shù)

var test = (x,y) =>  x + y ; 
test(1,3) // 4

函數(shù)額外知識(shí)點(diǎn):

1.每個(gè)javascrit中函數(shù)有一個(gè)內(nèi)置的對(duì)象arguments對(duì)象缩歪,它是一個(gè)類數(shù)組,我們可以用它達(dá)到函數(shù)重載的效果

function sum() {

     var  sum=0;

     for(var i = 0 ;i< arguments.length;i++) {

              sum+=arguments[i]

    }

    return sum

}

sum(1,2,3)  //6

2.函數(shù)的this指向個(gè)人理解:函數(shù)在執(zhí)行時(shí)谍憔,會(huì)在函數(shù)體內(nèi)部自動(dòng)生成一個(gè)this指針匪蝙。誰(shuí)直接調(diào)用產(chǎn)生這個(gè)this指針的函數(shù),this就指向誰(shuí)习贫。

 var a = 1

 function global(){

    var a = 2;

    console.log(this) //window

    console.log(this.a) //1

    console.log(a) //2

}

global() 等價(jià)于 window.global() //得出全局函數(shù)的this都是指向的window逛球,調(diào)用可以省略window

//如果函數(shù)作為對(duì)象的屬性被調(diào)用

var obj = {

    name: "師父",

    say: function() {

           console.log("大師兄," + this.name +  "被妖怪抓走了")

    },

    action: {

        name: "二師兄",

        me: "我老沙呀",

        say: function() {

            console.log("大師兄苫昌," + this.name +  "被妖怪抓走了");

            function whoSay() {

                    console.log(this) // window

                    console.log(this.me) //undefined

             }

             whoSay();
             // 因?yàn)槭菍儆谄胀ê瘮?shù)調(diào)用颤绕,但是并沒有通過 obj.action.say 直接調(diào)用,
             //只是自執(zhí)行,這個(gè)時(shí)候奥务,whoSay就是一個(gè)全局函數(shù)物独,因此該函數(shù)的
            //this指向的就是window,在window上找不到me故所以是undefined
        }

  }

}

obj.say(); //大師兄汗洒,師父被妖怪抓走了
obj.action.say(); //大師兄议纯,二師兄被妖怪抓走了

var elseObj=obj.say; 
elseObj(); // 注意此時(shí)的this指向?yàn)閣indow  大師兄,被妖怪抓走了

3.我們可以利用call溢谤,apply調(diào)用函數(shù)瞻凤,并改變了函數(shù)的this指向問題,他們區(qū)別傳參不同

function Animal (name){
    this.name = name
    this.showName = function() {
        console.log(this.name)
   }
}

function Cat(name) {
     Animal.call(this,name) //this指代函數(shù)Cat
}

function Dog(name) {
     Animal.apply(this,[name]) // 也可以寫成Animal.apply(this,[arguments]) 
}

var cat = new Cat('miaomiao');
console.log(cat.name) // miaomiao
console.log(cat.showName()) //miaomiao

var dog = new Dog('wangwang');
console.log(dog.name) //wangwang
console.log(dog.showName()) //wangwang
  1. 函數(shù)閉包 :在《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》:閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式世杀,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)阀参。
    作用:一個(gè)是可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中瞻坝。
    看個(gè)阮一峰老師最簡(jiǎn)單的閉包列子:
function f1(){
    var n=999;
    nAdd = function(){n+=1}
              function f2(){
                        return n
              }
      return f2;
 }

console.log(n) // 報(bào)錯(cuò)蛛壳,想要拿到函數(shù)內(nèi)部的n,那么用過一個(gè)函數(shù)返回

var result=f1();

result(); // 999

nAdd();

result(); // 1000 原因就在于f1是f2的父函數(shù)所刀,而f2被賦給了一個(gè)全局變量衙荐,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1浮创,因此f1也始終在內(nèi)存中忧吟,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收斩披。

好吧溜族,這東西呢仔細(xì)琢磨琢磨就行,現(xiàn)在我們拿一個(gè)列子來(lái)加深印象

 function A(){
        var funs=[];
        for(var i=0;i<10;i++){
           funs[i]=function(){
               return i;
           }
        }
        return funs; 
    }
    var funs = A();//定義funs[0]-funs[9]垦沉,10個(gè)函數(shù)
    console.log(funs[0]());//10
    console.log(funs[1]());//10
    console.log(funs[6]());//10

按理說我們腦袋反應(yīng)的應(yīng)該是0 煌抒,1 ,6 怎么全是10呢厕倍?
因?yàn)閳?zhí)行環(huán)境和變量對(duì)象在運(yùn)行函數(shù)時(shí)生成寡壮,在funs[0] () 的時(shí)候才產(chǎn)生真正的環(huán)境變量i,那么此時(shí)i是什么绑青,看return的時(shí)候诬像,顯然是10,所以返回的都是10了

我們用閉包改一下,j 加一個(gè)立即執(zhí)行函數(shù)正應(yīng)對(duì)了我們剛提到的執(zhí)行環(huán)境和變量對(duì)象在運(yùn)行函數(shù)時(shí)生成闸婴,那么此時(shí)的環(huán)境變量已經(jīng)變成了1坏挠,2,3....

 function A(){
        var funs=[];
        for(var i=0;i<10;i++){
           funs[i]=function B(num){
                   return function() {
                        console.log(num)
                  }
           }(i)
        }
        return funs; 
    }
  1. 函數(shù)遞歸:字面就是在函數(shù)里面調(diào)用自己邪乍,在滿足遞歸條件時(shí)需要多次調(diào)用降狠,比較著名的斐波那契數(shù)列fibonacci
    fibonacci數(shù)列為:[1, 1, 2, 3, 5, 8, 13, 21, 34 …],就是后一項(xiàng)等于強(qiáng)兩項(xiàng)的和对竣,看下代碼實(shí)現(xiàn)
function fibonacci(n) {
         if(n  <= 1) {
               return 1
         }
         return fibonacci(n-1) + fibonacci(n-2)
}
// 我們可以用閉包遞推來(lái)實(shí)現(xiàn)然這里也是使用了遞歸,
//但是閉包大大減少了遞歸的次數(shù)典型的用空間換時(shí)間的例子榜配。
var fibonacci = (function(){
  var arr = [0,1,1];  
  return function(n) {
    var res = arr[n];
    if(res) {
        return res;
    } else {
        arr[n]=fiba(n-1)+fiba(n-2);
        return arr[n];
    }
  }   
}(n)
//遞推法就是循環(huán)嘛
function fibonacci(n){
    var one = 1;
    var two = 1;
    for (var i = 3;i<=n; i++) {
        var three = one + two;
        one = two;
        two = three;
    }
    if(n==1 || n==2) {
        return one
    }
    return three
}

遞推法的效率最高否纬,其次是閉包,而遞歸法效率最低蛋褥。
閉包效率雖然相對(duì)遞歸法高了不少临燃,但是這種方法,如果使用不當(dāng)會(huì)造成內(nèi)存泄露烙心,

遞歸算法一般用于解決三類問題:

  • 數(shù)據(jù)的定義是按遞歸定義的膜廊。(Fibonacci函數(shù))
  • 問題解法按遞歸算法實(shí)現(xiàn)。(回溯)
  • 數(shù)據(jù)的結(jié)構(gòu)形式是按遞歸定義的淫茵。(樹的遍歷仍侥,圖的搜索)

但是遞歸算法解題的運(yùn)行效率較低端逼。在遞歸調(diào)用的過程當(dāng)中系統(tǒng)為每一層的返回點(diǎn)、局部量等開辟了棧來(lái)存儲(chǔ)初橘。遞歸次數(shù)過多容易造成棧溢出等沼溜。
如果使用循環(huán)不能解決,再考慮用遞歸

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末契耿,一起剝皮案震驚了整個(gè)濱河市椒惨,隨后出現(xiàn)的幾起案子碌奉,更是在濱河造成了極大的恐慌,老刑警劉巖碍论,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菲驴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡骑冗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門先煎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贼涩,“玉大人,你說我怎么就攤上這事薯蝎∫>耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵占锯,是天一觀的道長(zhǎng)袒哥。 經(jīng)常有香客問我,道長(zhǎng)消略,這世上最難降的妖魔是什么堡称? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮艺演,結(jié)果婚禮上却紧,老公的妹妹穿的比我還像新娘桐臊。我一直安慰自己,他們只是感情好晓殊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布断凶。 她就那樣靜靜地躺著,像睡著了一般巫俺。 火紅的嫁衣襯著肌膚如雪认烁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天介汹,我揣著相機(jī)與錄音却嗡,去河邊找鬼。 笑死痴昧,一個(gè)胖子當(dāng)著我的面吹牛稽穆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赶撰,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舌镶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了豪娜?” 一聲冷哼從身側(cè)響起餐胀,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瘤载,沒想到半個(gè)月后否灾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸣奔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年墨技,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挎狸。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扣汪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锨匆,到底是詐尸還是另有隱情崭别,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布恐锣,位于F島的核電站茅主,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏土榴。R本人自食惡果不足惜诀姚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玷禽。 院中可真熱鬧学搜,春花似錦娃善、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至炬丸,卻和暖如春瘫寝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稠炬。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工焕阿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人首启。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓暮屡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親毅桃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子褒纲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章钥飞,發(fā)現(xiàn)簡(jiǎn)書還為我保存起的...
    Jenaral閱讀 2,756評(píng)論 2 9
  • 一莺掠、 JS面向?qū)ο缶幊?1、 面向?qū)ο蠼榻B 什么是對(duì)象读宙? Everything is object (萬(wàn)物皆對(duì)象)...
    寵辱不驚丶?xì)q月靜好閱讀 834評(píng)論 0 2
  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,197評(píng)論 0 3
  • 函數(shù)只定義一次彻秆,但可能被執(zhí)行或調(diào)用任意次。JS函數(shù)是參數(shù)化的结闸,函數(shù)的定義會(huì)包括一個(gè)稱為形參的標(biāo)識(shí)符列表唇兑,這些參數(shù)在...
    PySong閱讀 319評(píng)論 0 0
  • 函數(shù)只定義一次,但可能被執(zhí)行或調(diào)用任意次桦锄。JS函數(shù)是參數(shù)化的幔亥,函數(shù)的定義會(huì)包括一個(gè)稱為形參的標(biāo)識(shí)符列表,這些參數(shù)在...
    PySong閱讀 853評(píng)論 0 0