【javascript】了解函式(function)很重要的筆記

雖然會寫 javascript ,但一直沒有好好花時間研究他,有時候常常寫到一些很奇怪的bug,其實都不了解他運作原理造成的。在看【javascript設計模式】時,就把自己覺得很重要的部份記錄下來(誰叫我健忘....),這篇拿來記錄一些對於函式(function)的重點。

函式的Hoisting

函式的宣告,或著變數的宣告,都會被提升到函式的最前面,假設我們原先的函式如下:

function one() {
  console.log('global one');
}

function two() {
  console.log('global two');
}

function hoistFun() {
  console.log(typeof one);
  console.log(typeof two);
  
  one();
  two();
}

hoistFun();
// 輸出結果

// function

// function

// global one

// global two

而提升的範例如下:

function one() {
  console.log('global one');
}

function two() {
  console.log('global two');
}

function hoistFun() {
  console.log(typeof one);
  console.log(typeof two);
  
  one();
  two();
  
  function one() {
    console.log('local one');
  }
  
  var two = function() {
    console.log('local two');
  }
}

hoistFun();
// 輸出結果:

// function

// undefined

// local one

// Uncaught TypeError: undefined is not a function

我們可以看到在 hoistFun() 內宣告的 one() 和變數 two 都被提升至 hoistFun() 這個函式的前面,覆蓋了原先全域的函式,這就是函式的Hoisting。

範例連結

回呼模式(callback function)

回呼是為了傳第一個函式進一個函式裡,並在適當的時候執行,基本的用法我們可以看看:

function two(callback) {
  var count1 = 1;
  (callback && typeof(callback) === "function") && callback();
  console.log(count1);
}

function three() {
  console.log('three run');
}

two(function() {
  console.log('callback run');
});

two(three);

當我們傳遞進去後,還是需要進行判斷,可以用:

(callback && typeof(callback) === "function") && callback();

來判斷傳送進來的參數是不是一個 function。

自建範例

但在回呼中,有時候會遇到回呼的對象是某個物件的方法,這時候如果用到 this.屬性 就有可能會遇到問題,可連同方法的物件一起傳送,如(參考javascript 設計模式第四章-68頁):

var xuan = {};
xuan.name = ''xuan';
xuan.email = function(accout) {
    console.log(this.name + '' + accout + '@gmail.com');
};

function two(callback, callback_obj) {
  (callback && typeof(callback) === "function") {
    callback.call(callback_obj, pare);
  };
}

參考:

  1. JavaScript callback function 理解
  2. Callback Functions in JavaScript

回傳函式

有時候我們會在某些函式中去回傳函式,如下:

function add() {
    console.log('1');
    return function() {
    console.log('part 2');
  }
}

我們將各種執行的可能結果寫出來:

add();
// part 1


add();
// part 1


add()();
// part 1

// part 2


var one = add();
// part 1


one();
// part 1

// part 2

closure(閉包)

而在上面範例的 var one = add();one 在此時就形成了一個closure(閉包),只有 return 的出去的函式可以對她內部的變數做存取,達到一個 pritive 的結果,實際來看一下範例:

function add() {
  var count = 0;
  return function() {
    console.log(count = count + 1);
    console.log('closure');
  };
};

add()();
// 1

// closure


add()();
// 1

// closure


var one = add();
one();
// 1

// closure


one();
// 2

// closure

可以看到我們的變數值這時候就可以達到儲存的效果,並不會因為函式執行完後就被回收掉。

立即函式

(待續.....)

Comments

comments powered by Disqus