[Day31] 函式

Day21 - 物件的基础概念2 中有提到函式是物件的一个子型别,所以它本身就是一个物件,但函式又与一般的物件有些需不同,详述如下:

函式的简介

函式通常会包括以下内容:

  1. 函式名称,但也可没有( ex: 匿名函式)
  2. 小括号 (),而小括号内可以有以 逗号 , 分开的多个参数
  3. 大括号 {},大括号内为程序码片段

以下为简单的函式范例:

透过 关键字 function 来宣告一个函式,而 fun 是这个函式的名子,小括号 () 内为此函式的参数,而在 大括号 {} 内写入程序码片段,并可在内使用 return 使函式回传值,最後可以利用 fun('参数');,呼叫此函式,也因 fun('参数'); 是表达式,可以回传值,因此也可以赋予到变数上

function fun(parameter1, parameter2) {
    var local = '区域变数'
    console.log(local)
    return parameter1 + parameter2;
}
var call = fun('参数1', '参数2');
console.log(call);

而函式与一般物件的不同在於:

  1. 可以被呼叫
  2. 包含程序码片段
  3. 函式可以有一个名称,但也可不需要( ex: 匿名函式)

函式的类型

函式可以被分为函式陈述式与函式表达式

函式陈述式

函式陈述式又称 具名函式,意思就是有名子的函式,可以直接利用名子呼叫函式

函式是否需要名称,在於函式是否能够被调用,可被调用就可省略
(ex: 当赋予到变数上,可直接使用变数呼叫,此函式就不需要定义名称)

function fun() {
    console.log(fun);
}

fun(); // 呼叫函式陈述式

/*
ƒ fun() {
    console.log(fun);
}
*/

不能使用函式陈述式的例子:

  • 立即函式
  • 物件内的方法

函式表达式

函式表达式,是先宣告一个变数,透过 = 运算子function 宣告的函式,赋予到此变数上,而此函式不一定需要名称,若 没有定义函式名称则为 匿名函式

因将函式赋予到 变数 fun 上,变数 fun 接收的是此函式的参考路径

var fun = function () {
    console.log(fun);
}

fun(); // 呼叫函式表达式

/*
ƒ fun() {
    console.log(fun);
}
*/

当具名函式赋予到变数上,也是函式表达式,但需要注意的是在此状况下,此具名函式只能在函式内被调用,如果在函式外调用则会出错

var fun = function fun2() {
    console.log(fun);
    console.log(fun2);
}

fun();

/*
ƒ fun2() {
    console.log(fun);
    console.log(fun2);
}

ƒ fun2() {
    console.log(fun);
    console.log(fun2);
}
*/

fun2(); // 因在函式外调用,故出现错误讯息
// Uncaught ReferenceError: fun2 is not defined

函式的提升

Day7 - 提升 章节有提到关於函式的提升,在此复习一下:

函式陈述式 会在创造阶段时,先在记忆体中将函式陈述式的所有内容做保留

function fn() { 
 // ...
}

fn();

运作过程:

// 1.创造阶段
function fn() { 
 // ...
}

// 1.执行阶段
fn();

函式表达式 创造阶段时只会将它的变数先在记忆体中保留空间,直到执行阶段才会将函式赋予给此变数,所以若要利用函式表达式,就必须等函式已经赋予到变数上,才能运行此函式

var fn = function () { 
 // ...
}

fn();

运作过程:

// 1.创造阶段
var fn;

// 1.执行阶段
fn = function () { 
 // ...
}

fn();

Airbnb 规范

在 Airbnb 的规范中,会建议尽量避免使用陈述式,使用为具名函式的函式表达式,这是为了在大型专案中,函式陈述式的提升性质可能会影响其他程序码运行,而使用具名函式的函式表达式而非用匿名函式,则是因具名函式因具有名子能更方便除错,以下范例取自 Airbnb 规范

// bad
function foo() {
  // ...
}

// bad
const foo = function () {
  // ...
};

// good
// lexical name distinguished from the variable-referenced invocation(s)
const short = function longUniqueMoreDescriptiveLexicalFoo() {
  // ...
};

参考文献

六角学院 - JavaScript 核心篇


<<:  Day31 - Windows 提权(2)-AlwaysInstallElevated、Unattended Installs、Bypassing UAC

>>:  [Python 爬虫这样学,一定是大拇指拉!] DAY30 - 结语

【Day8】:ADC电压采集

类比输入 自然界当中的讯号几乎为连续的,也就是我们常说的类比讯号,而对於单晶片或着电脑来说,我们能够...

[常见的自然语言处理技术] 重不重要?TF-IDF 会告诉你

前言 在自然语言处理的诸多课题如信息检索( information retrieval )和文本探勘...

NIST基础架构相关准则

NIST SP 800-41 R1(防火墙) NIST SP 800-92(日志管理) NIST ...

【没钱买ps,PyQt自己写】Day 4 - 重要的 Qt 程序逻辑观念,务必先有此观念後面才会懂自己在干嘛

看完这篇文章你会得到的成果图 (没有,今天不写程序,但要讲重要观念XD) PyQt 的程序逻辑 我特...

搜寻引擎优化入门篇:你不能不知道的响应式网页设计

随着行动浏览成为搜寻引擎主流,响应式网页设计也越来越重要,甚至能说在这几年,假设你的网页没有响应式设...