iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0

相信大家在學其他語言的時候,也常常會用的function的概念。但還是不免俗地來跟它聊聊。畢竟還是有那麼一兩點需要不一樣需要注意的地方。


回顧兩小無猜初次相見

小時候,數學老師說:function 就像一個工廠,把原物料扔進去,做一些加工,會產出產物。~~國小應該只有班導。~~所以一個function可能需要:參數(原物料)、一些動作(加工)、回傳值return(產物)。
function生產線


定義function的方法們

定義一個function(生產線),除了上面講的可能需要:參數(原物料)、一些動作(加工)、return值(產物)之外,還可能需要:function關鍵字(告訴電腦它是一條生產線,不是別的咚咚)、function名字。為甚麼我都用「可能」需要。因為有些有的時候不需要呀~

定義function的方法有三

  • function宣告
  • function運算式
  • new Function 聽說你效能運算上有點小弱,所以...先跳過

我們來做了一個easyCard悠遊卡的function吧。
預設裡面有押金100元。每次可以加值或是用掉x元,用完後回報你剩餘金額。

function宣告

function easyCard(x){
	//不要自己為是很貼心地加上數值型別(i.e. string int),或是寫 var x 會報錯的
	var deposit =100;
	var total = deposit + x;
	return total;
}

function運算式

烤(考)小鳥時間:為甚麼可以把function 另給一個變數var?
因為在JS中function 屬於引用類型的object(物件)。既然是個物件,當然就可以另給一個變數拉~

  • function名 可以省略,稱為匿名函式(Anonymous Function)
var easyCard = function (x){
								var deposit =100;
								var total = deposit + x;
								return total;
							}
  • function 名 也可以不要省略,但在function外的地方呼叫不到
var easyCard = function abc(x){
								var deposit =100;
								var total = deposit + x;
								return total;
							}

abc();
//Uncaught ReferenceError: abc is not defined

return裡面如果放一個算式

function add(x,y){
	return x+y;
}

function add1(x,y){
	return 
	x+y;
}

function add2(x,y){
	return; 
	x+y;
}

function add3(x,y){
	return( 
	x+y);
}

add(1,1);   //2   
add1(1,1)   //undefined
add2(1,1)   //undefined
add3(1,1)   //2

return 後方會自動幫我們插入分號。所以如果x+y換行,add1就相等於add2。
而return宣告後方的程式碼,電腦是無法抵達的,因此返回undefined。
避免換行電腦就翻臉不認人的情況,我們可以增加小括號(),像add3。


呼叫呼叫 function 出來~你的泡麵要爛掉了

剛剛abc()已經透露了,function的呼救方法就是後面加個()。

function easyCard(x){
	var deposit =100;
	var total = deposit + x;
	return total;
}

easyCard(100);  //200

忘記填參數

easyCard();     //Nan

該填參數的地方忘記填參數,不會報錯。如果是number會回饋Nan,其他則是undefined。
但是為甚麼呢?把undefined轉成number就知道啦~

Number(undefined)   //NaN

剛剛不小心在 var total = deposit + x; 的地方,讓電腦偷偷知道,total是一個number。
嘗試把他刪掉,的確回傳undefined。

function easyCard(x){
	var deposit =100;
	return x;
}

easyCard();     //undefined

加個默認值 加個蛋

為了避免這種忘記填參數的情形,我們可以幫參數加上默認值。
直接在參數後方加上=xxx

function easyCard(x=0){
	var deposit =100;
	var total = deposit + x;
	return total;
}

easyCard();     //100

變數的有效區域 - 想取走變數,你有通行證嗎?蛤

//全域變數
var deposit =500;
function easyCard(x=0){
	//區域變數 function內變數
	var deposit =100;
	var total = deposit + x;
	return total;
}

//function屬性
easyCard.deposit = 200;

console.log(deposit);              
console.log(easyCard())            
console.log(easyCard.deposit)      

猜得出來嗎,各位幼鳥們?

.

.

.

答案分別是500,100,200

  • console.log(deposit)是指從全域呼叫deposit,自然是呼叫到全域變數deposit=500
  • console.log(easyCard())指從全域呼叫easyCard,函式easyCard用到的deposit是function自己的deposit,deposit=100
  • console.log(easyCard.deposit)指從全域呼叫easyCard的屬性,也就是我們另外幫他另的easyCard.deposit = 200;。
    沒錯,你沒看錯,function可以有屬性,因為function是object嘛。

請注意console.log(easyCard.deposit)不可能是easyCard的內變數。因為外部不能訪問內部的變數。
→小結論:function內變數≠function物件的屬性

如果內部沒有設所需變數,腫麼辦?

如果easyCard這個function內部沒有設押金(deposit),會一層一層的往外找,找到為止。

//全域變數
var deposit =500;
function easyCard(x=0){
	//區域變數 function內變數
	//var deposit =100;
	var total = deposit + x;
	return total;
}

//function屬性
easyCard.deposit = 200;

console.log(easyCard(20))            //520

到全域也找不到會....

//全域變數
//var deposit =500;
function easyCard(x=0){
	//區域變數 function內變數
	//var deposit =100;
	var total = deposit + x;
	return total;
}

//function屬性
easyCard.deposit = 200;

console.log(easyCard(20))  //Uncaught ReferenceError: deposit is not defined            

廢話,當然是會報錯阿 Uncaught ReferenceError: deposit is not defined

全域變數 = 全域物件的屬性

var deposit =500;         //全域變數

console.log(this)         //window (是一個物件喔)
console.log(this.deposit) //500

剛剛說function的區域變數,不等於function物件的屬性。但是全域的狀況就不太一樣了,但是邏輯還是一樣滴~~待我稚鳥娓娓道來

我的理解是,window物件屬性是可以被全域訪問的,且全域變數可以在全域被訪問,所以全域變數會等於全域屬性。

同樣function物件屬性可以被訪問,但function內變數不可被區域外(i.e.全域)訪問,更精準的說是:function的內變數用完就丟,是要怎麼訪問的到呢?

function easyCard(x=0){
	//區域變數 function內變數
	var deposit =100;
	var total = deposit + x;
	return total;
}

console.log(easyCard.deposit)  //undefined

所以當我沒有設function屬性時,從區域外訪問easyCard.deposit會是undefined。
當我設function屬性時,從區域外訪問easyCard.deposit,就會是可以訪問到的function屬性值。

→小結論:雖然說變數在object中被稱為屬性,但訪問function這種object時,內變數用完就丟,所以內變數不會等於屬性。


參考資料

重新認識 JavaScript: Day 10 函式 Functions 的基本概念 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天


日常紀錄...
狀態:打完AZ,瘋狂發燒後,康復的第一天


上一篇
DOM 實作 換背景圖
下一篇
this指向who
系列文
前端幼鳥三十天養成記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言