[Day28] 函式

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 核心篇


<<:  Day29:今天来聊一下CEH中讲的Cryptography

>>:  Day28 React - Countdown Timer

Day5 认识JSX,简化你的程序码

一般写程序的时候,我会将HTML和Javascript分开来写,但react提供了JSX的语法,将h...

Day 11 Analyze images with the Computer Vision service

Computer vision - Process images is key to creatin...

Day14 Django资料库介绍

我们这几天已经学了一些Django的入门技巧了,但之後如果实作时,势必需要储存一些资料在後台。 但我...

宝塔Linux版升降级7.7版本脚本

复制代码保存*.sh,然后bash *.sh执行 #!/bin/bash PATH=/bin:/sb...

Day17 requests模组二

今天的影片内容为解释向网页服务器请求资料失败可能的原因 以及碰到「反爬虫机制」的应对方法 以下为影片...