




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在过去几年里,JavaScript有很多的更新。如果你想提升写代码的能力,这些更
新将会对你有非常大的帮助。
对于程序员来说,了解这门语言的最新发展是非常重要的。它能使你跟上最新趋
势,提高代码质量,在工作中出类拔萃,从而进一步提升你的薪资待遇。
特别地,如果你想学习像React、Angular或Vue这样的框架,你必须掌握这
些最新的特性。
最近,JavaScript增加了许多有用的功能,比如Nullishcoalescingoperator,
optionalchaining.Promises,async/await,ES6destructuring,等等。
那么现在,我们将探讨每个JavaScript开发者都应该知道的概念。
JavaScript中的Let和const
在ES6之前,JavaScript使用var关键字来声明变量,var只有全局作用域和函
数作用域,所谓全局作用域就是在代码的任何位置都能访问var声明的变量,而
函数作用域在变量声明的当前函数内部访问变量。此时是没有块级作用域的。
随着let和const这两个关键字的添加,JS增加了块级作用域的概念。
如何在JavaScript中使用let
当我们在用let声明变量时,用于声明一次之后就不能再以相同的名称重新声明
它。
//ESSCode
varvalue=W;
console.log(value);//
vav-value="kello";
co^ole.log(val(Ae)://hello
varvalue=30;
cok\$ole.log(value);//3(9
如上所示,我们多次使用var关键字重新声明了变量值。
在ES6之前,我们可以使用var重新声明之前已经声明过的变量,这就会导致了
一个问题:如果我们在不知情的情况下,在其他地方重新声明了该变量,很有可
能会覆盖原先变量的值,造成一些难以调试的问题。
所以,Let解决很好地解决此问题。当你使用let重新声明变量值时,将会报错。
//£S6Codd&tvalue=1。;
coiaso(e.(og(value);//IO
letvalue="hello11;//UMaughtSy^taxError:Identifier'value1alreadybeendeclared
但是,以下代码是合法的:
//ES6Code
letvalue=工。;
co^ole.log(value),//工。
value="hello";
co^ole.log(value);//hello
我们发现上面的代码看起来没什么问题,是因为我们重新给value变量赋了一个
新值,但是并没有重新声明。
我们来看下下面的代码:
//ES5Codevarinvalid=t^ue)if(isValid){
var八uhAber=工。;
co八sole.logCi八side:、^umfeer);//inside:工O
}c(mso怙JogCobttside:'number*);//outside:IO
如上所示,在使用var声明变量时,可以在if块之外访问该变量。
而使用let声明的number变量只能在if块内访问,如果在if块外访问将会报错。
我们来看下接下来的代码
//ES6Code
letisValid=tme;iF(isVah'd){
let八〃hber=工。;
c。八sole.logCinside:',八〃//inside:
}cov\sole,.\og{(outside:1,//Ui^caugktRefer©八ceError:i^ui^berisMtdefied
如上述代码所示,使用let分别在if块内、if块外声明了number变量。在if块
外,number无法被访问,因此会出现引用错误。
但是,如果变量number在if块外已经声明,将会出现下面的结果。
//ES6CodeletisValid=true;letnumber=20;
if(isValid){
letHumfeer=1O;
c。八so/c」og('inS/'de:,laumfaer);//inside:1。
)
1
coi^soledogCoutside:1numfaer);//outside:2.0
现在在单独的范围内有两个number变量。在if块外,number的值为20。
//ES5Codefor(vari=O;i<■i++){
co八so/c./ogS;
1
yco^sole.logCoutsidc:}i);//IO
当使用var关键字时,i在for循环之外也可以访问到。
//ES6Codefor(leti=6?;/<1。;i++){
co八os/e」og3;
)
1
coi^sole.log^outside:,i);//U八caughtReferei^ceError:iisnotdefined
而使用let关键字时,在for循环外部是不可访问的。
因此,正如上述示例代码所示,let声明的变量只能在块内部可用,而在块外部
不可访问。
我们可以使用一对大括号创建一个块,如下:
leti=ic>;
(
leti=20;
coinsole..log('iimid.e.:',i);//认side:2-0
i=30;
console.logCiagai^ji);//iagaii^:"50
}
coi^sole.logCoutride:'ji);//outside:1。
前面有提到,let在同一个块中不能重新声明变量,不过可以在另一个块中重新
声明。如上代码所示,我们在块内重新声明了i,并赋值20,该变量仅可在该块
中使用。
在块外,当我们打印变量时,我们得到的是10而不是之前分配的值,这是因为
块外,内部变变量i是不存在的。
如果在块外未声明变量,那么将会报错:
(
leti=20;
ccmsoElogCi八side:、i);//inside:2.0
i=3(P;
consol&.logCiagai^.'ji);//iagaii^:36?
)
co八sole.log('ob(tsi4e:Li);//U八caughtRefwenccE"":iisnot4。fined
如何在JavaScript使用const
const关键字在块级作用域中的工作方式与let关键字完全相同。因此,我们来
看下他们的区别。
const声明的变量为常量,其值是不能改变的。而let声明的变量,可以为其赋
一个新值,如下所示:
let八"nabcr=WjFiumfeer=20;
c。八so/eJog®uhAbe。//20
但是以下情况,我们不能这样使用consto
consttaumfaer=W;number=20;//UMaughtTypeError.Ass/?八MC八ttoconstantvariable.
我们甚至不能使用const像下面一样重新声明。
constAumfeer=2。;。。八so/eJog(八“小匕”);//2.0
covxstv\uw^bev=1。;//UMaughtSyntaxError:Identifier'八〃35。尸kasalreadybee■人
declared.
现在,看下面的代码:
constarr=卬2,,5,4];
〃".p“sk(5);conso/e./og(〃");//2,3>4>5]
我们说过const声明的常量,它的值永远不会改变——但是我们改变了上面的常
量数组并没有报错。这是为什么呢?
注意:数组是引用类型,而不是JavaScript的基本类型
实际存储在arr中的不是数组,而是数组存储的内存位置的引用(地址)。执行
arr.push(5),并没有改变arr指向的引用,而是改变了存储在那个引用上的值。
对象也是如此:
const。与={
name:'Davids
age:"50
obj.age=40;
coi^sole.log(obj);//{taame:'Davidsage:40]
这里,我们也没有改变。bj指向的引用,而是改变了存储在引用的值。
因此,上述的代码将会起作用,但下面的代码是无效的。
coi^stobj-{/Davidsage:309co八stobjl={八Wh'ke,age:40);
obj=objl://UkicaughtTypeError:八八2tocoi^sta^tvariable.
这样写会抛出异常,因为我们试图更改const变量指向的引用。
因此,在使用const时要记住一点:使用const声明常量时,不能重新声明,也
不能重新赋值。如果声明的常量是引用类型,我们可以更改存储在引用的值。
同理,下面的代码也是无效的。
constarr=[a2>3,4];
arr=[W,2。,3(9];//UMaugk\tTypeError:Assynmenttoco^stai^tvariable.
总结:
•关键字let和const在JavaScript中添加块级作用域。
・当我们将一个变量声明为let时,我们不能在同一作用域(函数或块级作用
域)中重新定义或重新声明另一个具有相同名称的let变量,但是我们可以
重新赋值。
•当我们将一个变量声明为const时,我们不能在同一作用域(函数或块级
作用域)中重新定义或重新声明具有相同名称的另一个const变量。但是,
如果变量是引用类型(如数组或对象),我们可以更改存储在该变量中的值。
好了,我们继续下一个话题:promises。
JavaScript中的promises
对于很多新开发者来说,promises是JavaScript中较难理解的部分。ES6中原生
提供了Promise对象,那么Promise究竟是什么呢?
Promise对象代表了未来将要发生的事件,用来传递异步操作的消息、。
如何创造一个promise
使用promise构造函数创建一个promise,如下所示:
cohstpromise=newPro^ise(functioia(resol\/e,reject){
});
Promise的构造函数接收一个函数作为参数,并且在内部接收两个参数:resolve,
rejectoresolve和reject参数实际上是我们可以调用的函数,具体取决于异步
操作的结果。
Promise有三种状态:
•pending:初始状态,不是成功或失败状态。
•fulfilled:表示操作成功完成。
・rejected:表示操作失败。
当我们创建Promise时,它处于等待的状态。当我们调用resolve函数时,它将
进入已完成状态。如果调用reject,他将进入被拒绝状态。
在下面的代码中,我们执行了一个异步操作,也就是setTimeout,2秒后,调用
resolve方法。
cov\stpromise=new八ctio八(reso(vc)reject){
setTiw<eoiAt(funetioi^.(){
coi^stSUM=4+5;
}>ZOOO\
});
我们需要使用以下方法注册一个回调.then获得Ipromise执行成功的结果,如
下所示:
constpromise=MWProkvuMe®八由。八(烟。/%reject){
$etTikv\eout(fuMtio^(){
constsum=4+5;
%so"e(s〃3);
},2。。。);
});
proi^ise.thei^(fuMtiok\(result){
co^ole.log(resul't);//夕
1);
then接收一个参数,是函数,并且会拿到我们在promise中调用resolve时传的
的参数。
如果操作不成功,则调用reject函数:
constprom/se=newPsoMise(fiA八ctio八(忆solve,reject){
setTi^eout(fuMtio^.(){
constsum=44-5+W;
if(i,NaN(WM))(
rejectf'Errorwhilecalculatingsum/);
}eke(
}
}>2.000);
1);
prokvu'se.tke八(functi。八(rcsu/t){
console.log(result);
如果sum不是一个数字,那么我们调用带有错误信息的reject函数,否则我们
调用resolve函数。
执行上述代码,输出如下:
GBEWWOCorwolBSotfOMNstwoftcPertormanoeMemoryM»cMcnS«x*wyRedux©i0X
囱010P♦。FMvi«v«a♦2rtddBA。
•constpcoait*-r<wFroalwtfunctret4lw<
WtTtwowt(fun«UOfl()<v
co*»t,♦•«・$・,•*»
rejectCCrr^rwMU*ls
>re3s“olve((«ua);
>
>.2«M>|
»:
9<MlM.thcn(rwfKtlo:n(rctult><
»c:oftMle.loq(r»s«UI
“iwi”<«prMin9»>
O»Unc«vfht(in*rwl»e>«hlWC«l<wUtiafaCtfrUfr-Mtt/Xl
»
调用reject函数会抛出一个错误,但是我们没有添加用于捕获错误的代码。
需要调用catch方法指定的回调函数来捕获并处理这个错误。
pro^v\isc.tkeia(fuiactio^(re$ult){
co八so/cJog(Kes川切
}).catck(fuMtioia(error){
con.sole.log(error);
});
输出如下:
G归EMnwMsCcr«0i»SourcmNatwortiPertarmanceMamoryAopAcatmSeoMWyUgNhouMReduxO-X
(B0top•&F««rOetaimt*,1htddan。
><on%t"oai,e-newFroaiM<iof>(rviolve,rejectI<
MtTi*MMt(runCtlOA()<
co*>tt,g•4♦5••••:
lf<iy«4M<*uaH<
reiectClrrorwhilecalculAtln$)SUB.'))
>elw(
j
)
Lzmh
>h
60J1*.t*(,UftCt3QA<fl”<
CORMU.
>hCAtch(fu^tion(erfor)(
l«t(err«rH
1h
Gpend,忖)
trr®r«Mk(•IcvUtlngSUB.YMU1;D
所以建议大家在使用promise时加上catch方法,以此来避免程序因错误而停止
运行。
链式操作
我们可以向单个promise添加多个then方法,如下所示:
prowu'se.theMf〃八泡。八化){
1
co八sole.logCfirst.thenhandler);
returnresult;
}).仍"(f〃八由。八(%6川t){
coi^sole.togCsecond.the八handler1);
co八so/a/og(resH±);
八ct/'。八(error){
co^ole.log(error);
});
当添加多个then方法时,前一个then方法的返回值将自动传递给下一个then
方法。
住@Pwriomano*MemoryA^ptcattonSae(/VyL^WtouwRMm0tx
㈣0top♦eR»«rDetmJitw«t«,2nddan。
>co*«tpraa&w•ncFroaiie(furxtton(r«Mlw.reject)<
MtTLaeout<f«MtU«(><
con»t*WB•4•5;
'trrartAileCAlcul^ttntwa.*];
>•“<
r«M\vflsuB);
1.2-h
»;
proaiw.fwiul1«A()<
<8”1,・U9《”"N.thenMMWr*):
returnmult;
I09I*t«<or4.the*haneu*');
console.Kog<r«sult);
>).catch(fuRctiofilerrocJ<
c«Atol«.log(«rr«r):
»,
tint.tFMMltrMUJUUJ
M<oM.«MnMMWr«uu;u
如上图所示,我们在第一个then方法中输出字符串,并将接收的参数result(sum)
返回给下一个resulto
在下一个then方法中,输出字符串,并输出上一个then方法传递给它的resulto
如何在JavaScript中延迟promise的执行
很多时候,我们不希望立即创建promise,而是希望在某个操作完成后再创建。
我们可以将promise封装在一个函数中,然后从函数中返回promise,如下所示:
createProM,seO{
returnMWPKO0/u'se(f〃八c力'0八(reso/ve,reject){
setTikv\eout(fuMtioi^(){
constsum=4+5;
if(isNaN(siAM》{
reject^Errorwhilecalculatiin.gsum.');
}else{
resolve(suM);
}
},ZOOO);
});
)
这样,我们就可以通过函数将参数传递给promise,达到动态的目的。
functioncreateProi^i^ajb){
returnnewProm/se(fuiactio^(resolve,reject){
setTikv\eout(fun.ctioia(){
constsum-a+b;
iF(isNaA/(s〃⑹){
wh/lecalculatingsum/);
}else(
resolve(sum);
1
}>2000);
!);
)
createPromisefl..S)
.tkei^(fiAMtio^.(output){
consote,tog(output);//q
1);
//OR
createPro侬阳工024)
,the>i^(fu^ctio^(output){
co^ole.log(output);//34
1);
G(5JEMrwmComot*SomcrnNMworKPeftarnwv*MemorySeo/*/UgroouwRedux。:X
(BQlop■<3>HMTiwato.Q
>fuftctionb)(
retvmce»Pe«i乂《,5<"8lp«W・,eject)(
ietTiBeowt|fw**tlonO(
ce*ttMB•••b;
rejecH'Erer-♦caUuUtingMh.);
>«lte<
r«tolv«(tua);
>.MM);
cre«t«*roalt<(:.S)
.then!runctlontevtpwt»<
CMMU.lM(Mftput);//•
»:
creatcFro«t»etl«t24l
.thCA(fUIKt10«t(Outputi<
COAMU.lMfevtput);〃34
>h
»,rw
MRU4I16
乂1MU4;2J
此外,我们只能向resolve或reject函数传递一个值。如果你想传递多个值到
resolve函数,可以将它作为一个对象传递,如下:
coi^stpromise=MWProkvuMe(f〃八cti。八(reso/vc,reject){
setTikv\eout(fuMtioi^(){
constsum=44-S;
resoke({
a:4j
b:S,
SUM
!);
卜200。);
!);
proM/'sc.the八(fa八d。八(resu任)(
conso/c」og(resHt);
}).catck(fiA^ctioia(crror){
c。八so/e」og(e"。。
!);
GflBarmnttCorwoiaSCMOMNeewortcPvtormanc*MomorySecureUgrtriouMRodui0:X
E)QlopV®FnarDvteJtWMf♦2Q
><on»tproaite-f»•B“<hX»mon«FOlvt.rej«t><
MtTiaeowKfunctiOflO<
«*»t3•4•51
r«Mlv«<<
•:%
bi九
MM
»;
>.NMU
»J
p*Mi*e.thentfwnctlon(rciwlt>{
COAMU.loqI"SultI;
18le,r©r»(
conMle.lo9lerrorh
»:
“roej”卯)
»(at4,bt,.s9)«2»:U
>I
如何在JavaScript中使用箭头函数
上述示例代码中,我们使用常规的ES5语法创建了promise。但是,通常使用箭
头函数代替ES5语法,如下:
constprom/se=MWPromrseffreso/ve,reject)=>{
setTi'meoutfO=>{
constsum=44-5+W;
if(i,NaN(suM))(
rejectf'Errorwhilecalculatingsum/);
}else(
reso/ve(sum);
1
上2.000);
1);
prom/se.thmffresult)=>{
con$ole.log(result);
});
你可以根据自己需要使用ES5或ES6语法。
ES6Import和Export语法
在ES6之前,我们在一个HTML文件中可以使用多个script标签来引用不同的
JavaScript文件,如下所示:
scripttyp^'toct/javascript11src=,,hokv\e.js,,></$cript><scripttype="text/javascript"
,,,,
s^c二"profilejs"〉〈/scHpt〉〈scHpttype="text/javascHpt"src=userjs></scr/pt>
但是如果我们在不同的JavaScript文件中有一个同名的变量,将会出现命名冲突,
你实际得到的可能并不是你期望的值。
ES6增加了模块的概念来解决这个问题。
在ES6中,我们编写的每一个JavaScript文件都被称为模块。我们在每个文件中
声明的变量和函数不能用于其他文件,除非我们将它们从该文件中导出并、在另
一个文件中得到引用。
因此,在文件中定义的函数和变量是每个文件私有的,在导出它们之前,不能在
文件外部访问它们。
export有两种类型:
・命名导出:在一个文件中可以有多个命名导出
・默认导出:单个文件中只能有一个默认导出
JavaScript中的命名导出
如下所示,将单个变量命名导出:
exportconsttemp="Thisissometext",
如果想导出多个变量,可以使用大括号指定要输出的一组变量。
consttempi="ThisisSOMCdummy±extl>”;c。八st="Thisissomedummy
textZ"export{tempi,);
需要注意的是,导出语法不是对象语法。因此,在ES6中,不能使用键值对的形
式导出。</pre>
//ThisisinvalidsyntaxofexportmES&
export{kcgl:valued,keg2:valueZ)
import命令接受一对大括号,里面指定要从其他模块导入的变量名。
import{tempi,仅岬2)from
注意,不需要在文件名中添加js扩展名,因为默认情况下会考虑该拓展名。
//importfromh(八ctions.jsfilefromcurrentdirectory
import{tCFwpl,tew\p2}from',/f〃八cti。八s';
//importfrokv\fu八ctio八sjsfileFKOHAparentofcurrentdirectory
import{tempi}from'../缶八ctio^s';
提示一点,导入的变量名必须与被导入模块对外接口的名称相同。
因此,导出应使用:
//coi^stant$J$
exportconstPI=3.14159;
那么在导入的时候,必须使用与导出时相同的名称:
import{PI}from'./co八
//Thiswillthrow4八error
import{PiValue}fromL/co八S±M2S';
如果想为输入的变量重新命名,可以使用as关键字,语法如下:
import{PI〃sPiValue}from'./c。八stcmts';
我们以为PI重命名为PiValue,因此不能再使用PI变量名。
导出时也可使用下面的重命名语法:
//C。八st〃ntsjs
constPl=3.1415^;
export{PIasPIValue);
然后在导入是,必须使用PIValue。
import{PIValue}from'/constants';
命名导出某些内容之前必须先声明它。
export'hello1;//thiswillresult/认error
exportco八stgreeting=//thiswillwork
export{'David');//ThiswiHresult/herror
exportconstobject={H<ame:'David*);//Thisw/71work
我们来看下面的validations.js文件:
//utils/validatioi^s.js
coi^stisValidEi^ail=Ftmc力'。八(
if(/人[八@J+@[八@j+\.[A@\.]{2(
return"ei^.ailisvalid'1;
}dse(
return"ei^ailisiiavalid";
}
c。八stisValidPhoM=fuiactioi^(plaoM)(
ifC/A[\\GM{3}[\\)]W{3}-\^{4^/.test(pho^e)){
return"phoMnumfeerisvalid11;
}eke(
return"phoM八〃麻。0匕isinvalid”;
)
);
fimctionisEyv\pty(value){
if(/八\s4/.tesqvaMe)){
return“stringisekwptyorcontains。八也spaces";
}else(
return"stringis八。temptya^ddocsMtcontainspaces”;
}
}
export{isValidEMaiLisValiAPho八e,isEmptg);
在indexjs中,我们可以使用如下函数:
//Mdex.js
import{isEMptg,isValidEMail}from"./uti^/validatio^11;
ccmsoElogC'isEmptg:",i^Ei^pty("abcd"y);//i^Ei^pty:strMgisnotemptyataddoes八。七
coi^taii^spaces
,,>
co八so@(og(〃isValidEMail:",i$ValidEi^ail(abc@Hgi^.ail.coi^\"));//isValidE^v\ail:ei^ailis
valid
l,,,y
co八sole.log("isVa(idEmai(:",i^ValidEi^ail(ab^c^^lgkv\ail.cokv\),);//i^ValidE^vxail:ei^ailis
invalid
JavaScript的默认导出
如上所述,单个文件中最多只能有一个默认导出。但是,你可以在一个文件中使
用多个命名导出和一个默认导出。
要声明一个默认导出,我们需要使用以下语法:
〃C。八S±M±SJS
constname='David1;
exportdefault
在导入时就不需要再使用花括号了。
importnamefrom'./constants1;
如下,我们有多个命名导出和一个默认导出:
//C0八StMtsjS
exportconstPl=3.X4XS9;
exportconstAGE=3(9;
constNAME="Davi#;
exportdefaultNAME;
此时我们使用import导入时,只需要在大括号之前指定默认导出的变量名。
//NAMEisdefaultexportav\dPIai^dAGEarei^ai^edexportshere
importNAME,{PLAGE}from'./coi^sta^ts';
使用exportdefault导出的内容,在导入的时候,import后面的名称可以是任
意的。
//C。八s±〃ntsjs
constAGE=36?;
exportdefaultACE;
importmyA5efrom’./constants';
co^olc.log(kv\yAge);//30
另外,exportdefault的变量名称从Age至ijmyAge之所以可行,是因为只能存
在一个exportdefault。因此你可以随意命名。还需注意的是,关键字不能在声
明变量之前。
//C。八stMtsJs
exportdefaultcov\stAGE=3<9;//Thisis〃八error〃八dwillMtwork
因此,我们需要在单独的一行使用关键字。
//constaiatsjs
constAGE=
exportdefaultAGE;
不过以下形式是允许的:
〃c。八sta八tsjs
exportdefault{
八〃"Billy11,
age:40
手;
并且需要在另一个文件中使用它
沁portuserfrom7c。八stmts';
co八so/e」og(〃scr.八//Billy
c。八so/cJog(〃scH.〃ge);//40
还有,可以使用以下语法来导入constants.js文件中导出的所有变量:
//testjs
import*asconstantsfrom。/c。八S±M2S';
下面,我们将导入所有我们constants.js存储在constants变量中的命名和export
defaulto因此,constants现在将成为对象。
//C。八stantsjs
exportcov\stUSERNAME="David";
exportdefault{
name:
age:40
};
在另一个文件中,我们按一下方式使用。
//testjs
import*asc。八s标mtsfrom'./constants';
c。八so/e」og(coiastants.USERNAME);//David
console.Iog(constak\ts.default);//{八aMc:"BiHgLage:40)
c(msole.(og(c(mstantsdefabdt.age);//40
也可以使用以下方式组合使用命名导出和默认导出:
//COMMCSJS
constPl=3.141S9;constAGE=36);
coiostUSERNAME=,,Davidu;
constUSER={
Mme:
age:4。
);
export{PI,AGE,USERNAME,USER.asdefault};
importUSER.,{PI,AGE,USERNAME}from"./constants";
总而言之:
ES6中,一个模块就是一个独立的文件,该文件内部的所有变量,外部都无法获
取。如果想从外部读取模块内的某个变量,必须使用export关键字导出该变量,
使用import关键字导入该变量。
JavaScript中的默认参数
ES6增加了一个非常有用的特性,即在定义函数时提供默认参数。
假设我们有一个应用程序,一旦用户登录系统,我们将向他们显示一条欢迎消息,
如下所示:
fuMtioiasMowMfirstName){
return^Welcomeback,)"+
)
z
c。八so/c」og(showMessage(JoW));//Welcomeback,Joh八
但是,如果数据库中没有用户名,那该怎么办呢?所以,我们首先需要检查是否
提供了firstName,然后再显示相应的信息。
在ES6之前,我们必须写这样的代码:
fimction5owMcss〃ge(6K如〃kvu){
if(fidtName){
return"Welcomeback,11+f/rstAJame;
}eke{
r血m"We/comeback,Guest';
}
}
co八so/e」og(skowMess〃geCJok"));//Welcomeback,John
c。八so/e./og(showMcss〃geO);//Welcomeback,Guest
但现在使用ES6提供的默认参数,我们可以这样写:
fimctio八showMcssage(fidtName='Gue^t1){
return^Welcomeback,"+f/rstName;
1
co八so/e」og(showMess4ge(U0k"));//Welcomeback,John
c。八so/c」og(showMessagcO);//Welcomeback,Guest
函数的默认参数可以为任意值。
functiondisp(ay(a=工Ob=20,c=b){
co八sole.logS,b,c);
)
display();//XO2.02.0
d印砥(40);//402。2。
display^,70);//17070
display^,犯70);//工3070
在上面的代码中,我们没有提供函数的所有参数,实际代码等同于:
displag。;//等同于八def/'八cW,undefined,〃八defined)
displag(4O);等同于d/MpSg(4O,”八defined,ui^defiMd)
display^j70);等同于disp/〃g(:lj7。,〃八deFi八ed)
因此,如果传递的参数是undefined,则对应的参数将使用默认值。
我们还可以将对象或计算值指定为默认值,如下:
constdefaultuser={
‘Jane,
location:'NY',
job:'SoftwareDeveloper1
};
constdisplay=(user=def〃川tUser,age=/2)=>{
cok\sole.log(u$erJage);
displayO;
/*output
(
iaai^v\e:'JaM'j
location:'NY'>
job:'SoftwareDeveloped
}30
*/
ES5代码如下:
//ESSCode
fu^ctioiagetUsc”(page,resiAggender,nationality){
varparams=
if(page===O||page){
params+=
)
if(results)
params+=、res〃怙s=${「es〃/ts}&';
1
if(gmde吟
params十二、gen
)
if(i^atioi^ality){
params+=、八〃七‘。八{八at,。八HitgF;
]
fetckChttp^Z/ra^doi^user.^e/api/?'+params)
.仍©八他八ctioMresp。八sc){
returnresponsejsoM);
1)
.tke^(fuMtioi^.(iresult){
cok\$ole.log(re$ult);
!)
.catch(fiAiactioia(error){
co八so/eJogCcrr0rserror);
!);
]
g况Use”(。,工GZs);
在这段代码中,我们通过在getUsers函数中传递各种可选参数来进行API调用。
在进行API调用之前,我们添加了各种if条件来检查是否添加了参数,并基于此
构造查询字符串,如下所示:
使用ES6的默认参数则不必添这么多if条件,如下所示:
=O,res川区=工O,genHer=^ale^Mtioiaality='"s'){
fetchCkttps://ra^do^iAser.^e/api/?${page}&cr^ults-$\jresults}&:ge^.d^-${ge^der\&:
iaatioi^aIity=^{natioMIityy)
.then(fu八c力0Mresponse){
return%spo八sejs。八0;
))
coi^sole.log(result);
!)
.catck(fuiactio^(error){
cohso/c./ogCcrrorSerror);
1);
}
g况Used。;
这样一来,代码得到了大量的简化,即便我们不为getUsers函数提供任何参数
时,它也能采用默认值。当然,我们也可以传递自己的参数:
getUsers(l,2。,'female1,?勿);
它将覆盖函数的默认参数。
null不等于未定义
注意:定义默认参数时,null和undefined是不同的。
我们来看下面的代码:
fuMtioiadisplay(iaai^\e='David1,age=location=
c。八age,location
}
displayCDavid'j3S);//David3SNY
displayCDavid'j3S,〃八defined);//David3SNY
//OR
displagCDavid、"55)(A八defined);//David.3SNY
displayCDavid'j"55'八川D;//David3S八〃"
当我们传递null作为参数时,它实际是给location参数赋一个空值,与undefined
不一样。所以它不会取默认值"NY"。</pre>
Atotype.includes
ES7增加了数组的includes方法,用来判断一个数组是否包含一个指定的值,如
果是返回true,否则false。
//ES5Code
constnumbers="two","three","four"];coiasole.log(nuMbers.inde-xOf("OM")>-1);//
true.covxsole.log(in.uM.bers.im.d.exOf("fiv&")>-1);//false
数组可以使用includes方法:
//E
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高三一模考试试题及答案
- 科目一模拟考试题及答案
- 2025年中药执业资格真题及答案
- 淮阳消防笔试真题及答案
- 化学推理能力提升试题
- 化学反应速率影响因素试题
- 古代进阶考试题及答案大全
- 小考科学真题试卷及答案
- 2025年建工类培训考试题及答案
- 2025年陇桥学院考试试题及答案
- 执行力与领导力培训
- 公路工程技术规范题库
- IPD项目-TR1要素评审表
- 拌合站拆除作业安全技术交底
- 胰岛素的种类及应用(共26张PPT)
- 数学教师简历模板3篇
- 汽车租赁合同协议书合同
- YY/T 1269-2015血液透析和相关治疗用水处理设备常规控制要求
- GB/T 96.1-2002大垫圈A级
- 完整版隧道项目消防工程施工组织设计方案
- 《内科学》人卫第9版教材
评论
0/150
提交评论