函數、函數表達式、做用域、閉包

函數聲明和函數表達式

var f = function () {
    
}

function f() {
    
}

函數聲明和函數表達式的主要區別是,函數聲明會被前置,而函數表達式做爲變量,會被提高。面試

下方是js執行時的邏輯

// 前置和變量提高
var f;
function f() {
    
}

f = function () {
    
}

一道題考察知識掌握狀況

var f = function () {
    console.log(1)
}

function f() {
    console.log(2)
}

f();

上方代碼直接結果爲:1閉包

Function函數了解一下,不怎麼經常使用

圖片描述

閉包(不說話,看圖就能夠)

圖片描述

一道題考察閉包(循環閉包)
var o = [];
for(var i = 0; i < 5; i++){
    o[i] = function () {
        console.log(i)
    }
}

o[3]();

以上代碼執行結果爲:5函數

如何改進以上代碼,使o[1]=>1; o[2]=>2; ..., 那就是利用閉包咯

var o = [];
for(var i = 0; i < 5; i++){
    (function (i) {
        o[i] = function () {
            console.log(i);
        }
    })(i);
}

o[3]();

以上代碼執行結果爲:3spa

解析:

  • 第一種方法中,只有o[3]()執行時,纔會用i,而i卻一直在變化,等到o[3]()執行時,i已是5了;
  • 第二種方法,運用了閉包,由於o[i]函數的上一層是自執行函數,所以所運用到的閉包參數i,在for循環過程當中就已經固定,再也不變化。等到o[3]執行時,固定的閉包參數就被釋放了出來
  • 被面試的時候被問到這道題,問我除了閉包有沒有其它方法,沒答出來,原來將var改爲let就能夠了,居然不知道
var o = [];
for(let i = 0; i < 5; i++){
    o[i] = function () {
        console.log(i)
    }
}

閉包第二種應用場景(封裝變量)

(function () {
  var name = 'LHX';
  var age = 30;
  var export = {};
  
  export.getName = function () {
      return name;
  }
  export.setName = function (newName) {
      name = newName;
  }
  
  window.export = export;
})();

只有經過釋放出來的export才能訪問私有變量

閉包的缺陷

閉包中的變量由於可能還會被內部函數用到,所以所佔內存一直不能被釋放,致使內存浪費code

相關文章
相關標籤/搜索