函數(shù)表達式

說在前面 :

我們定義函數(shù)有兩種方式:1.函數(shù)聲明式 2.函數(shù)表達式

函數(shù)聲明式:存在函數(shù)聲明提升,所以可以在聲明之前調(diào)用


sayHi() //hi

    //函數(shù)聲明式

    function sayHi(){

      console.log('hi')

    }

函數(shù)表達式:在使用前必須被賦值


sayHi() //報錯

    //函數(shù)聲明式

    var sayHi = function(){

      console.log('hi')

    }

1.遞歸
說明:遞歸函數(shù)就是函數(shù)自己又調(diào)自己的情況 ,使用遞歸實現(xiàn)階乘 :


function factorial(num){

      if(num <= 1){

        return 1;

      }else{

        return num * factorial(num-1)

      }

    }

但是這樣,會有一種情況,執(zhí)行下面代碼時,中間把函數(shù)factorial賦值為null,遞歸調(diào)用時內(nèi)部的factorial已經(jīng)不函數(shù)了 ,報錯,解決方式是用argument.calee,他會指向正在執(zhí)行的函數(shù) (嚴格模式無法使用)


var fun = factorial;

    factorial = null

    alert(fun(4))

2.1閉包
說明:閉包是啥?是有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),常見閉包方式,一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),內(nèi)部函數(shù)訪問了外部變量


function createFunction(property){

      return function(obj1,obj2){

        var val1 = obj1[property];

        var val2 = obj2[property];

        if(val1>val2){

          return 1;

        }else{

          return -1;

        }

      }

    }



// 創(chuàng)建函數(shù)

    var compare = createFunction('name')

    // 調(diào)用函數(shù)

    var result = compare({name:"nike"},{name:'grays'})

    // 解除對匿名函數(shù)的引用

    compare = null

內(nèi)部匿名函數(shù) 使用著外部函數(shù)的參數(shù),是可以使用到的,原因涉及到作用域鏈的問題 ,一個函數(shù)被調(diào)用時,會創(chuàng)建一個執(zhí)行環(huán)境和相應(yīng)的作用鏈,,使用argumens和其他命名參數(shù)初始化活動對象,它的外部函數(shù)的對象處在第二位,依次往外類推

2.2閉包與變量
因為保存的是整個變量對象,不是某個特殊的值,會造成一個問題,閉包只能取到函數(shù)中任何變量的最后一個值

我們看下面的例子


function createFun(){

      var result = new Array()

      for(var i = 0;i < 10;i++){

        result[i] = function(num){

          // return function(){

            return num

          // };

        }

      }

      return result;

    }

數(shù)組的每一項都是一個函數(shù),兒每個函數(shù)內(nèi)部存儲的值均為 循環(huán)結(jié)束時的10,解決方法 我們可以利用函數(shù)的自執(zhí)行保存每一個值


function createFun(){

      var result = new Array()

      for(var i = 0;i < 10;i++){

        result[i] = (function(num){

          return function(){

            return num

          };

        }(i))()

      }

      return result;

    }

    console.log(createFun()) //[0,1,2...9]

2.3 關(guān)于this指向
在閉包中,我們返回的是一個匿名函數(shù),匿名函數(shù)的執(zhí)行環(huán)境是全局的,所以該匿名函數(shù)里的this 是通常指向window,一般下面的情況 ,this就指向window


var name = "window";

    var obj ={

      name :"obj",

      getName : function(){

        return function(){

          return this.name

        }

      }

    }

    console.log("name====>",obj.getName()())  //window

想要this指向調(diào)用方法的對象,我們可以在return匿名函數(shù)之前定義一個屬性保留this指向


var name = "window";

    var obj ={

      name :"obj",

      getName : function(){

        var that = this

        return function(){

          return that.name

        }

      }

    }

    console.log("name====>",obj.getName()())  //obj

2.4 內(nèi)存泄漏
因為內(nèi)部函數(shù)始終使用著外部的屬性或者元素,意味著元素無法釋放而被銷毀,我們有必要在使用結(jié)束后,將其設(shè)為null,具體見2.1

3.模仿塊級作用域
原因:

1.js中不存在塊級作用域

2.只要在變量定義在函數(shù)的活動對象里,在函數(shù)內(nèi)部隨處可以調(diào)用

3.多次聲明不會報錯,對后面的聲明忽略

方法:匿名函數(shù)模仿塊級作用域


(function(){

      //塊級作用域

    })()

實例:


function kuai(count){

      (function(){

      //塊級作用域

      for(var i = 0;i < count;i++){

        alert(i)

      }

    })()

    alert(i)  //出了塊級作用域  i undefined

    }

4.私有變量
js沒有私有成員的概念,每個屬性都是對象共有的。但是js有私有變量的定義。任何定義在函數(shù)中的變量,都是私有變量,如果我們再函數(shù)內(nèi)部創(chuàng)建一個閉包,閉包通過自己的作用域鏈訪問函數(shù)私有變量,

我們把能訪問私有變量&私有方法的公有方法稱為特權(quán)方法


function myObj(){

      // 私有變量  私有函數(shù)

      var  priPropoty = 10;

      function priFunction(){

        return false

      }

      //特權(quán)方法

      this.pubFunction = function(){

        priPropoty++;

        return  priFunction();

      }

    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容