函數(shù)進(jìn)階
一、概述
ES2015為函數(shù)賦予的新特性:
立即執(zhí)行函數(shù)
閉包
函數(shù)默認(rèn)值
箭頭函數(shù)
async函數(shù)
二、立即執(zhí)行函數(shù)
立即執(zhí)行函數(shù)顧名思義,就是聲明之后立刻執(zhí)行的函數(shù):
(function(){console.log("hello world");})()
函數(shù)體被一個(gè)小括號(hào)包裹起來,然后后面緊跟著一個(gè)小括號(hào),
這樣當(dāng)函數(shù)被聲明之后,就立刻被調(diào)用。
立即執(zhí)行函數(shù)通常用來封裝代碼,例如下面的例子:
(function(){let a=10;let b=20;
console.log(a+b)})()
這段代碼可以輸出a + b的結(jié)果,但是立即執(zhí)行函數(shù)外部是不能訪問a和b的,因此成功達(dá)到了封裝的目的。
在比較古老的js代碼中,大家都是這種方法來封裝代碼的,但是ES2015自帶模塊化語法,因此這種封裝的寫法就不太常見了,
大家只做了解即可。
三、閉包
閉包是定義在函數(shù)內(nèi)部的函數(shù),我們用立即執(zhí)行函數(shù)編寫一個(gè)閉包的例子
(function(){
function add(a,b){
return a+b
}
let result=add(10,20)
console.log(result)
})()
立即函數(shù)內(nèi)部的add函數(shù)就是閉包,閉包的特點(diǎn)是具有全局性,閉包內(nèi)部的this關(guān)鍵字會(huì)指向全局對(duì)象window。
我們來看一個(gè)示例來演示這個(gè)特性
四、函數(shù)默認(rèn)值
在ES2015版本之前,我們可以通過下面的方法設(shè)置函數(shù)參數(shù)的默認(rèn)值
代碼如下所示:
function fun1(x,y){
x=x||100;
y=y||200;
returnx+y;
}
ES2015中新增了更直觀的設(shè)置函數(shù)默認(rèn)值的方法
//es2015+設(shè)置默認(rèn)值
function fun2(x=100,y=200){
return x+y;
}
五、箭頭函數(shù)
在此前的課程中,我們學(xué)習(xí)了兩種方法定義函數(shù),
函數(shù)聲明
函數(shù)表達(dá)式
在ES2015中增加了箭頭函數(shù)的語法,可以使用=>來定義函數(shù):
//函數(shù)聲明
function add(a,b){returna+b}
//函數(shù)表達(dá)式
const add=function(a,b){returna+b}
//箭頭函數(shù)
const add=(a,b)=>{returna+b;}
=>左側(cè)的括號(hào)存放參數(shù)
=>右側(cè)的花括號(hào)存放函數(shù)體。
以上展示了一個(gè)完整的箭頭函數(shù)的語法,這其實(shí)還不能體現(xiàn)箭頭函數(shù)的優(yōu)勢。
箭頭函數(shù)第一個(gè)優(yōu)勢是,簡寫的箭頭函數(shù)可以讓代碼更簡潔
如果函數(shù)只有一個(gè)形參,那么可以省略參數(shù)外面的括號(hào)。
如果函數(shù)體只有一個(gè)表達(dá)式作為返回值,可以省略花括號(hào)和return關(guān)鍵字
實(shí)例代碼如下所示
const fun=x=>x*x;
let result=fun(6);
console.log(result)//36;
面相對(duì)象
一、面相對(duì)象概述
首先面向?qū)ο笫且环N編程思想,是一種通過多個(gè)對(duì)象互相協(xié)作完成處理流程的編程思路【是對(duì)現(xiàn)實(shí)世界中一類事物的抽象,
在編程中可以理解為是一種建立現(xiàn)實(shí)世界事物的模型】
推及到廣義上,面向?qū)ο笠呀?jīng)越了程序設(shè)計(jì)和軟件開發(fā),我認(rèn)為面向?qū)ο笥质且环N思維方式,不局限于編程語言,
甚至不局限編程本身,它把復(fù)雜的需求、業(yè)務(wù)邏輯抽絲剝繭、逐個(gè)分析。
主要分為:類的聲明定義、對(duì)象的創(chuàng)建使用、面向?qū)ο髶碛械奶卣鳌救筇卣鳎悍庋b、繼承、多態(tài)】
封裝:體現(xiàn)了對(duì)象對(duì)于敏感數(shù)據(jù)的保護(hù)特征
繼承:體現(xiàn)了代碼的復(fù)用和功能的擴(kuò)展
多態(tài):體現(xiàn)了不同操作環(huán)境中代碼的多樣性【程序的健壯性】
二、基于原型的面向?qū)ο?/a>
在ES2015版本之前,JavaScript是沒有類的概念的,我們可以使用構(gòu)造函數(shù)來模擬一個(gè)類,這在我們之前的課程中已經(jīng)講解過了,這里我們簡單復(fù)習(xí)一下。
創(chuàng)建一個(gè)貓的構(gòu)造函數(shù)
function Cat(name,age){
this.name=name;
this.age=age;
}
var cat=new Cat("miaomiao",2);
console.log(cat.name);
在上面的代碼中,我們定義了一個(gè)構(gòu)造函數(shù)Cat,通過var關(guān)鍵字創(chuàng)建了一個(gè)變量cat,cat有兩個(gè)屬性,name和age。我們可以直接輸出cat.name;
我們可以通過原型屬性為構(gòu)造函數(shù)添加方法,例如我們給這個(gè)Cat添加一個(gè)shout方法,讓這只貓可以叫
代碼如下所示:
function Cat(name,age){
this.name=name;
this.age=age;
}
Cat.prototype.shout=function(){
console.log("喵喵喵!")
}
var cat=newCat("miaomiao",2);
cat.shout();
這樣貓就有了shout方法,可以調(diào)用shout方法讓貓叫。
通過上面的代碼,我們可以模擬一個(gè)類的概念,但是這樣的寫法與真正面相對(duì)象語言的寫法相比,確實(shí)更難以理解。所以ES2015中增加了類的概念。
三、ES2015中的面向?qū)ο?/a>
基于原型的繼承方式,雖然實(shí)現(xiàn)了代碼復(fù)用,但是行文松散且不夠流暢,可閱讀性差,不利于實(shí)現(xiàn)擴(kuò)展和對(duì)源代碼進(jìn)行有效的組織管理。不得不承認(rèn),基于類的繼承方式在語言實(shí)現(xiàn)上更健壯,且在構(gòu)建可服用代碼和組織架構(gòu)程序方面具有明顯的優(yōu)勢。所以,ES2015+中提供了基于類class的語法。但class本質(zhì)上是ES2015+提供的一顆語法糖,正如我們前面提到的,JavaScript是一門基于原型的面向?qū)ο笳Z言。
我們可以用class來定義一個(gè)類,然后可以在這個(gè)類中定義構(gòu)造函數(shù),方法和屬性。
代碼如下所示:
class Cat{
constructor(name,age){
this.name=name;
this.age=age;
}
shout(){
console.log("喵喵喵");
}
}
let cat=newCat("miaomiao",2);
cat.shout();
上面的這段代碼與第二個(gè)案例的代碼功能是完全一樣的,但是通過class關(guān)鍵之定義一個(gè)貓的類,讓這個(gè)類更像是一個(gè)整體,而非一個(gè)個(gè)零散的prototype組合起來的一個(gè)功能。