FUNCTION

相信大家在学其他语言的时候,也常常会用的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,疯狂发烧後,康复的第一天


<<:  Day 18 - SwiftUI开发学习2(Toggle切换)

>>:  第2砍 - 临阵磨枪

DAY19 浅谈深度学习

我们在前面算是完整的介绍了使用机器学习的方法来做资料分析,在剩下最後11天的时间,我想把自己在暑假所...

2.4.9 Design System - Input Checkbox/Radiobox

人生真的很奇妙 可能在某个时间轴曾经跟某个人的时间轴交错 但当下是不认识的 然後在几年过後又再次交...

【从实作学习ASP.NET Core】Day04 | View 视图

昨天成功建立了 Controller 也得到了回传值,但它终究只是字串,所以今天要让他正式传入网页...

Day 8 - 初探Vue Component

在Vue的世界中,是由一个又一个的元件所构成,而我们可以透过自订元件的方式量身打造客制化的元件并进行...

AE极光制作2-Day8

接续昨天的练习:https://ithelp.ithome.com.tw/articles/1026...