欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

javascript工程,JavaScriPt

Web前端工程師應(yīng)該知道的JavaScript使用小技巧

今天小編要跟大家分享的文章是關(guān)于Web前端工程師應(yīng)該知道的JavaScript使用小技巧。任何一門技術(shù)在實(shí)際中都會(huì)有一些屬于自己的小技巧。同樣的,在使用JavaScript時(shí)也有一些自己的小技巧,只不過(guò)很多時(shí)候有可能容易被大家忽略。而在互聯(lián)網(wǎng)上,時(shí)不時(shí)的有很多同行朋友會(huì)總結(jié)(或收集)一些這方面的小技巧。

民權(quán)網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,民權(quán)網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為民權(quán)成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的民權(quán)做網(wǎng)站的公司定做!

今天在這篇文章中,小編會(huì)整理一些大家熟悉或不熟悉的有關(guān)于JavaScript的小技巧,希望能夠?qū)Υ蠹业膶W(xué)習(xí)和工作有所幫助。

一、數(shù)組

先來(lái)看使用數(shù)組中常用的一些小技巧。

01、數(shù)組去重

ES6提供了幾種簡(jiǎn)潔的數(shù)組去重的方法,但該方法并不適合處理非基本類型的數(shù)組。對(duì)于基本類型的數(shù)組去重,可以使用...new

Set()來(lái)過(guò)濾掉數(shù)組中重復(fù)的值,創(chuàng)建一個(gè)只有唯一值的新數(shù)組。

constarray=[1,1,2,3,5,5,1]

constuniqueArray=[...newSet(array)];

console.log(uniqueArray);

Result:(4)[1,2,3,5]

這是ES6中的新特性,在ES6之前,要實(shí)現(xiàn)同樣的效果,我們需要使用更多的代碼。該技巧適用于包含基本類型的數(shù)組:undefined、null、boolean、string和number。如果數(shù)組中包含了一個(gè)object,function或其他數(shù)組,那就需要使用另一種方法。

除了上面的方法之外,還可以使用Array.from(newSet())來(lái)實(shí)現(xiàn):

constarray=[1,1,2,3,5,5,1]

Array.from(newSet(array))

Result:(4)[1,2,3,5]

另外,還可以使用Array的.filter及indexOf()來(lái)實(shí)現(xiàn):

constarray=[1,1,2,3,5,5,1]

array.filter((arr,index)=array.indexOf(arr)===index)

Result:(4)[1,2,3,5]

注意,indexOf()方法將返回?cái)?shù)組中第一個(gè)出現(xiàn)的數(shù)組項(xiàng)。這就是為什么我們可以在每次迭代中將indexOf()方法返回的索引與當(dāng)索索引進(jìn)行比較,以確定當(dāng)前項(xiàng)是否重復(fù)。

02、確保數(shù)組的長(zhǎng)度

在處理網(wǎng)格結(jié)構(gòu)時(shí),如果原始數(shù)據(jù)每行的長(zhǎng)度不相等,就需要重新創(chuàng)建該數(shù)據(jù)。為了確保每行的數(shù)據(jù)長(zhǎng)度相等,可以使用Array.fill來(lái)處理:

letarray=Array(5).fill('');

console.log(array);

Result:(5)["","","","",""]

03、數(shù)組映射

不使用Array.map來(lái)映射數(shù)組值的方法。

constarray=[

{

ame:'大漠',

email:'w3cplus@#'

},

{

ame:'Airen',

email:'airen@#'

}

]

constname=Array.from(array,({name})=name)

Result:(2)["大漠","Airen"]

04、數(shù)組截?cái)?/p>

如果你想從數(shù)組末尾刪除值(刪除數(shù)組中的最后一項(xiàng)),有比使用splice()更快的替代方法。

例如,你知道原始數(shù)組的大小,可以重新定義數(shù)組的length屬性的值,就可以實(shí)現(xiàn)從數(shù)組末尾刪除值:

letarray=[0,1,2,3,4,5,6,7,8,9]

console.log(array.length)

Result:10

array.length=4

console.log(array)

Result:(4)[0,1,2,3]

這是一個(gè)特別簡(jiǎn)潔的解決方案。但是,slice()方法運(yùn)行更快,性能更好:

letarray=[0,1,2,3,4,5,6,7,8,9];

array=array.slice(0,4);

console.log(array);

Result:[0,1,2,3]

05、過(guò)濾掉數(shù)組中的falsy值

如果你想過(guò)濾數(shù)組中的falsy值,比如0、undefined、null、false,那么可以通過(guò)map和filter方法實(shí)現(xiàn):

constarray=[0,1,'0','1','大漠','#',undefined,true,false,null,'undefined','null',NaN,'NaN','1'+0]

array.map(item={

returnitem

}).filter(Boolean)

Result:(10)[1,"0","1","大漠","#",true,"undefined","null","NaN","10"]

06、獲取數(shù)組的最后一項(xiàng)

數(shù)組的slice()取值為正值時(shí),從數(shù)組的開(kāi)始處截取數(shù)組的項(xiàng),如果取值為負(fù)整數(shù)時(shí),可以從數(shù)組末屬開(kāi)始獲取數(shù)組項(xiàng)。

letarray=[1,2,3,4,5,6,7]

constfirstArrayVal=array.slice(0,1)

Result:[1]

constlastArrayVal=array.slice(-1)

Result:[7]

console.log(array.slice(1))

Result:(6)[2,3,4,5,6,7]

console.log(array.slice(array.length))

Result:[]

正如上面示例所示,使用array.slice(-1)獲取數(shù)組的最后一項(xiàng),除此之外還可以使用下面的方式來(lái)獲取數(shù)組的最后一項(xiàng):

console.log(array.slice(array.length-1))

Result:[7]

07、過(guò)濾并排序字符串列表

你可能有一個(gè)很多名字組成的列表,需要過(guò)濾掉重復(fù)的名字并按字母表將其排序。

在我們的例子里準(zhǔn)備用不同版本語(yǔ)言的JavaScript

保留字的列表,但是你能發(fā)現(xiàn),有很多重復(fù)的關(guān)鍵字而且它們并沒(méi)有按字母表順序排列。所以這是一個(gè)完美的字符串列表(數(shù)組)來(lái)測(cè)試我們的JavaScript小知識(shí)。

varkeywords=['do','if','in','for','new','try','var','case','else','enum','null','this','true','void','with','break','catch','class','const','false','super','throw','while','delete','export','import','return','switch','typeof','default','extends','finally','continue','debugger','function','do','if','in','for','int','new','try','var','byte','case','char','else','enum','goto','long','null','this','true','void','with','break','catch','class','const','false','final','float','short','super','throw','while','delete','double','export','import','native','public','return','static','switch','throws','typeof','boolean','default','extends','finally','package','private','abstract','continue','debugger','function','volatile','interface','protected','transient','implements','instanceof','synchronized','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','await','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof'];

因?yàn)槲覀儾幌敫淖兾覀兊脑剂斜恚晕覀儨?zhǔn)備用高階函數(shù)叫做filter,它將基于我們傳遞的回調(diào)方法返回一個(gè)新的過(guò)濾后的數(shù)組。回調(diào)方法將比較當(dāng)前關(guān)鍵字在原始列表里的索引和新列表中的索引,僅當(dāng)索引匹配時(shí)將當(dāng)前關(guān)鍵字push到新數(shù)組。

最后我們準(zhǔn)備使用sort方法排序過(guò)濾后的列表,sort只接受一個(gè)比較方法作為參數(shù),并返回按字母表排序后的列表。

在ES6下使用箭頭函數(shù)看起來(lái)更簡(jiǎn)單:

constfilteredAndSortedKeywords=keywords

.filter((keyword,index)=keywords.lastIndexOf(keyword)===index)

.sort((a,b)=a

這是最后過(guò)濾和排序后的JavaScript保留字列表:

console.log(filteredAndSortedKeywords);

Result:['abstract','arguments','await','boolean','break','byte','case','catch','char','class','const','continue','debugger','default','delete','do','double','else','enum','eval','export','extends','false','final','finally','float','for','function','goto','if','implements','import','in','instanceof','int','interface','let','long','native','new','null','package','private','protected','public','return','short','static','super','switch','synchronized','this','throw','throws','transient','true','try','typeof','var','void','volatile','while','with','yield']

08、清空數(shù)組

如果你定義了一個(gè)數(shù)組,然后你想清空它。通常,你會(huì)這樣做:

letarray=[1,2,3,4];

functionemptyArray(){

array=[];

}

emptyArray();

但是,這有一個(gè)效率更高的方法來(lái)清空數(shù)組。你可以這樣寫:

letarray=[1,2,3,4];

functionemptyArray(){

array.length=0;

}

emptyArray();

09、拍平多維數(shù)組

使用...運(yùn)算符,將多維數(shù)組拍平:

10、從數(shù)組中獲取最大值和最小值

可以使用Math.max和Math.min取出數(shù)組中的最大小值和最小值:

constnumbers=[15,80,-9,90,-99]

constmaxInNumbers=Math.max.apply(Math,numbers)

constminInNumbers=Math.min.apply(Math,numbers)

console.log(maxInNumbers)

Result:90

console.log(minInNumbers)

Result:-99

另外還可以使用ES6的...運(yùn)算符來(lái)完成:

constnumbers=[1,2,3,4];

Math.max(...numbers)

Result:4

Math.min(...numbers)

Result:1

二、對(duì)象

在操作對(duì)象時(shí)也有一些小技巧。

01、使用...運(yùn)算符合并對(duì)象或數(shù)組中的對(duì)象

同樣使用ES的...運(yùn)算符可以替代人工操作,合并對(duì)象或者合并數(shù)組中的對(duì)象。

//合并對(duì)象

constobj1={

ame:'大漠',

url:'#'

}

constobj2={

ame:'airen',

age:30

}

constmergingObj={...obj1,...obj2}

Result:{name:"airen",url:"#",age:30}

//合并數(shù)組中的對(duì)象

constarray=[

{

ame:'大漠',

email:'w3cplus@#'

},

{

ame:'Airen',

email:'airen@#'

}

]

constresult=array.reduce((accumulator,item)={

return{

...accumulator,

[item.name]:item.email

}

},{})

Result:{大漠:"w3cplus@#",Airen:"airen@#"}

02、有條件的添加對(duì)象屬性

不再需要根據(jù)一個(gè)條件創(chuàng)建兩個(gè)不同的對(duì)象,以使它具有特定的屬性。為此,使用...操作符是最簡(jiǎn)單的。

constgetUser=(emailIncluded)={

return{

ame:'大漠',

blog:'w3cplus',

...emailIncluded{email:'w3cplus@#'}

}

}

constuser=getUser(true)

console.log(user)

Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}

constuserWithoutEmail=getUser(false)

console.log(userWithoutEmail)

Result:{name:"大漠",blog:"w3cplus"}

03、解構(gòu)原始數(shù)據(jù)

你可以在使用數(shù)據(jù)的時(shí)候,把所有數(shù)據(jù)都放在一個(gè)對(duì)象中。同時(shí)想在這個(gè)數(shù)據(jù)對(duì)象中獲取自己想要的數(shù)據(jù)。

在這里可以使用ES6的Destructuring特性來(lái)實(shí)現(xiàn)。比如你想把下面這個(gè)obj中的數(shù)據(jù)分成兩個(gè)部分:

constobj={

ame:'大漠',

blog:'w3cplus',

email:'w3cplus@#',

joined:'2019-06-19',

followers:45

}

letuser={},userDetails={}

({name:user.name,email:user.email,...userDetails}=obj)

{name:"大漠",blog:"w3cplus",email:"w3cplus@#",joined:"2019-06-19",followers:45}

console.log(user)

Result:{name:"大漠",email:"w3cplus@#"}

console.log(userDetails)

Result:{blog:"w3cplus",joined:"2019-06-19",followers:45}

04、動(dòng)態(tài)更改對(duì)象的key

在過(guò)去,我們首先必須聲明一個(gè)對(duì)象,然后在需要?jiǎng)討B(tài)屬性名的情況下分配一個(gè)屬性。在以前,這是不可能以聲明的方式實(shí)現(xiàn)的。不過(guò)在ES6中,我們可以實(shí)現(xiàn):

constdynamicKey='email'

letobj={

ame:'大漠',

blog:'w3cplus',

[dynamicKey]:'w3cplus@#'

}

console.log(obj)

Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}

05、判斷對(duì)象的數(shù)據(jù)類型

使用Object.prototype.toString配合閉包來(lái)實(shí)現(xiàn)對(duì)象數(shù)據(jù)類型的判斷:

constisType=type=target=`[object${type}]`===Object.prototype.toString.call(target)

constisArray=isType('Array')([1,2,3])

console.log(isArray)

Result:true

上面的代碼相當(dāng)于:

functionisType(type){

returnfunction(target){

return`[object${type}]`===Object.prototype.toString.call(target)

}

}

isType('Array')([1,2,3])

Result:true

或者:

constisType=type=target=`[object${type}]`===Object.prototype.toString.call(target)

constisString=isType('String')

constres=isString(('1'))

console.log(res)

Result:true

06、檢查某對(duì)象是否有某屬性

當(dāng)你需要檢查某屬性是否存在于一個(gè)對(duì)象,你可能會(huì)這樣做:

varobj={

ame:'大漠'

}

if(obj.name){

console.l

Web前端工程師應(yīng)該知道的JavaScript的10個(gè)難點(diǎn)!

今天小編要跟大家分享的文章是關(guān)于Web前端工程師應(yīng)該知道的JavaScript的10個(gè)難點(diǎn)。相信很多正在學(xué)習(xí)Web前端知識(shí)的小伙伴對(duì)于JavaScript存在很多疑問(wèn),為了幫助大家更好的學(xué)習(xí)Web前端知識(shí),成為一名優(yōu)秀的web前端工程師,今天小編為大家分享了這篇Web前端應(yīng)該知道的JavaScript難點(diǎn)的問(wèn)題,下面我們一起看一看吧!

1、立即執(zhí)行函數(shù)

立即執(zhí)行函數(shù),即ImmediatelyInvokedFunctionExpression

(IIFE),正如它的名字,就是創(chuàng)建函數(shù)的同時(shí)立即執(zhí)行。它沒(méi)有綁定任何事件,也無(wú)需等待任何異步操作:

1.(function(){

2.

3.//代碼

4.

5.//...

6.

7.})();

function(){}是一個(gè)匿名函數(shù),包圍它的一對(duì)括號(hào)將其轉(zhuǎn)換為一個(gè)表達(dá)式,緊跟其后的一對(duì)括號(hào)調(diào)用了這個(gè)函數(shù)。立即執(zhí)行函數(shù)也可以理解為立即調(diào)用一個(gè)匿名函數(shù)。立即執(zhí)行函數(shù)最常見(jiàn)的應(yīng)用場(chǎng)景就是:將var變量的作用域限制于你們函數(shù)內(nèi),這樣可以避免命名沖突。

2、閉包

對(duì)于閉包(closure),當(dāng)外部函數(shù)返回之后,內(nèi)部函數(shù)依然可以訪問(wèn)外部函數(shù)的變量。

1.(function(){

2.

3.//代碼

4.

5.//...

6.

7.})();

代碼中,外部函數(shù)f1只執(zhí)行了一次,變量N設(shè)為0,并將內(nèi)部函數(shù)f2賦值給了變量result。由于外部函數(shù)f1已經(jīng)執(zhí)行完畢,其內(nèi)部變量N應(yīng)該在內(nèi)存中被清除,然而事實(shí)并不是這樣:我們每次調(diào)用result的時(shí)候,發(fā)現(xiàn)變量N一直在內(nèi)存中,并且在累加。為什么呢?這就是閉包的神奇之處了!

3、使用閉包定義私有變量

通常,JavaScript開(kāi)發(fā)者使用下劃線作為私有變量的前綴。但是實(shí)際上,這些變量依然可以被訪問(wèn)和修改,并非真正的私有變量。這時(shí),使用閉包可以定義真正的私有變量:

1.functionProduct(){

2.

3.varname;

4.

5.this.setName=function(value){

6.name=value;

7.};

8.

9.this.getName=function(){

10.returnname;

11.};

12.}

13.

14.varp=newProduct();

15.p.setName("Fundebug");

16.

17.console.log(p.name);//輸出undefined

18.console.log(p.getName());//輸出Fundebug

代碼中,對(duì)象p的的name屬性為私有屬性,使用p.name不能直接訪問(wèn)。

4、prototype

每個(gè)JavaScript構(gòu)造函數(shù)都有一個(gè)prototype屬性,用于設(shè)置所有實(shí)例對(duì)象需要共享的屬性和方法。prototype屬性不能列舉。JavaScript僅支持通過(guò)prototype屬性進(jìn)行繼承屬性和方法。

1.functionRectangle(x,y)

2.{

3.this._length=x;

4.this._breadth=y;

5.}

6.

7.Rectangle.prototype.getDimensions=function()

8.{

9.return{

10.length:this._length,

11.breadth:this._breadth

12.};

13.};

14.

15.varx=newRectangle(3,4);

16.vary=newRectangle(4,3);

17.

18.console.log(x.getDimensions());//{length:3,breadth:4}

19.console.log(y.getDimensions());//{length:4,breadth:3}

代碼中,x和y都是構(gòu)造函數(shù)Rectangle創(chuàng)建的對(duì)象實(shí)例,它們通過(guò)prototype繼承了getDimensions方法。

5、模塊化

JavaScript并非模塊化編程語(yǔ)言,至少ES6落地之前都不是。然而對(duì)于一個(gè)復(fù)雜的Web應(yīng)用,模塊化編程是一個(gè)最基本的要求。這時(shí),可以使用立即執(zhí)行函數(shù)來(lái)實(shí)現(xiàn)模塊化,正如很多JS庫(kù)比如jQuery以及我們Fundebug都是這樣實(shí)現(xiàn)的。

1.varmodule=(function(){

2.varN=5;

3.

4.functionprint(x){

5.console.log("Theresultis:"+x);

6.}

7.

8.functionadd(a){

9.varx=a+N;

10.print(x);

11.}

12.

13.return{

14.description:"Thisisdescription",

15.add:add

16.};

17.})();

18.

19.

20.console.log(module.description);//輸出"thisisdescription"

21.

22.module.add(5);//輸出“Theresultis:10”

所謂模塊化,就是根據(jù)需要控制模塊內(nèi)屬性與方法的可訪問(wèn)性,即私有或者公開(kāi)。在代碼中,module為一個(gè)獨(dú)立的模塊,N為其私有屬性,print為其私有方法,decription為其公有屬性,add為其共有方法。

6、變量提升

JavaScript會(huì)將所有變量和函數(shù)聲明移動(dòng)到它的作用域的最前面,這就是所謂的變量提升(Hoisting)。也就是說(shuō),無(wú)論你在什么地方聲明變量和函數(shù),解釋器都會(huì)將它們移動(dòng)到作用域的最前面。因此我們可以先使用變量和函數(shù),而后聲明它們。但是,僅僅是變量聲明被提升了,而變量賦值不會(huì)被提升。如果你不明白這一點(diǎn),有時(shí)則會(huì)出錯(cuò):

1.console.log(y);//輸出undefined

2.

3.y=2;//初始化y

上面的代碼等價(jià)于下面的代碼:

1.vary;//聲明y

2.

3.console.log(y);//輸出undefined

4.

5.y=2;//初始化y

為了避免BUG,開(kāi)發(fā)者應(yīng)該在每個(gè)作用域開(kāi)始時(shí)聲明變量和函數(shù)。

7、柯里化

柯里化,即Currying,可以是函數(shù)變得更加靈活。我們可以一次性傳入多個(gè)參數(shù)調(diào)用它;也可以只傳入一部分參數(shù)來(lái)調(diào)用它,讓它返回一個(gè)函數(shù)去處理剩下的參數(shù)。

1.varadd=function(x){

2.returnfunction(y){

3.returnx+y;

4.};

5.};

6.

7.console.log(add(1)(1));//輸出2

8.

9.varadd1=add(1);

10.console.log(add1(1));//輸出2

11.

12.varadd10=add(10);

13.console.log(add10(1));//輸出11

代碼中,我們可以一次性傳入2個(gè)1作為參數(shù)add(1)(1),也可以傳入1個(gè)參數(shù)之后獲取add1與add10函數(shù),這樣使用起來(lái)非常靈活。

8、apply,call與bind方法

JavaScript開(kāi)發(fā)者有必要理解apply、call與bind方法的不同點(diǎn)。它們的共同點(diǎn)是第一個(gè)參數(shù)都是this,即函數(shù)運(yùn)行時(shí)依賴的上下文。

三者之中,call方法是最簡(jiǎn)單的,它等價(jià)于指定this值調(diào)用函數(shù):

1.varuser={

2.name:"RahulMhatre",

3.whatIsYourName:function(){

4.console.log(this.name);

5.}

6.};

7.

8.user.whatIsYourName();//輸出"RahulMhatre",

9.

10.varuser2={

11.name:"NehaSampat"

12.};

13.

14.user.whatIsYourName.call(user2);//輸出"NehaSampat"

·apply方法與call方法類似。兩者唯一的不同點(diǎn)在于,apply方法使用數(shù)組指定參數(shù),而call方法每個(gè)參數(shù)單獨(dú)需要指定:

·apply(thisArg,[argsArray])

1.varuser={

2.greet:"Hello!",

3.greetUser:function(userName){

4.console.log(this.greet+""+userName);

5.}

6.};

7.

8.vargreet1={

9.greet:"Hola"

10.};

11.

12.user.greetUser.call(greet1,"Rahul");//輸出"HolaRahul"

13.user.greetUser.apply(greet1,["Rahul"]);//輸出"HolaRahul"

使用bind方法,可以為函數(shù)綁定this值,然后作為一個(gè)新的函數(shù)返回:

1.varuser={

2.greet:"Hello!",

3.greetUser:function(userName){

4.console.log(this.greet+""+userName);

5.}

6.};

7.

8.vargreetHola=user.greetUser.bind({greet:"Hola"});

9.vargreetBonjour=user.greetUser.bind({greet:"Bonjour"});

10.

11.greetHola("Rahul")//輸出"HolaRahul"

12.greetBonjour("Rahul")//輸出"BonjourRahul"

9、memoization

Memoization用于優(yōu)化比較耗時(shí)的計(jì)算,通過(guò)將計(jì)算結(jié)果緩存到內(nèi)存中,這樣對(duì)于同樣的輸入值,下次只需要中內(nèi)存中讀取結(jié)果。

1.functionmemoizeFunction(func)

2.{

3.varcache={};

4.returnfunction()

5.{

6.varkey=arguments[0];

7.if(cache[key])

8.{

9.returncache[key];

10.}

11.else

12.{

13.varval=func.apply(this,arguments);

14.cache[key]=val;

15.returnval;

16.}

17.};

18.}

19.

20.

21.varfibonacci=memoizeFunction(function(n)

22.{

23.return(n===0||n===1)?n:fibonacci(n-1)+fibonacci(n-2);

24.});

25.

26.console.log(fibonacci(100));//輸出354224848179262000000

27.console.log(fibonacci(100));//輸出354224848179262000000

代碼中,第2次計(jì)算fibonacci(100)則只需要在內(nèi)存中直接讀取結(jié)果。

10、函數(shù)重載

所謂函數(shù)重載(method

overloading),就是函數(shù)名稱一樣,但是輸入輸出不一樣。或者說(shuō),允許某個(gè)函數(shù)有各種不同輸入,根據(jù)不同的輸入,返回不同的結(jié)果。憑直覺(jué),函數(shù)重載可以通過(guò)if...else或者switch實(shí)現(xiàn),這就不去管它了。jQuery之父John

Resig提出了一個(gè)非常巧(bian)妙(tai)的方法,利用了閉包。

從效果上來(lái)說(shuō),people對(duì)象的find方法允許3種不同的輸入:

0個(gè)參數(shù)時(shí),返回所有人名;1個(gè)參數(shù)時(shí),根據(jù)firstName查找人名并返回;2個(gè)參數(shù)時(shí),根據(jù)完整的名稱查找人名并返回。

難點(diǎn)在于,people.find只能綁定一個(gè)函數(shù),那它為何可以處理3種不同的輸入呢?它不可能同時(shí)綁定3個(gè)函數(shù)find0,find1與find2啊!這里的關(guān)鍵在于old屬性。

由addMethod函數(shù)的調(diào)用順序可知,people.find最終綁定的是find2函數(shù)。然而,在綁定find2時(shí),old為find1;同理,綁定find1時(shí),old為find0。3個(gè)函數(shù)find0,find1與find2就這樣通過(guò)閉包鏈接起來(lái)了。

根據(jù)addMethod的邏輯,當(dāng)f.length與arguments.length不匹配時(shí),就會(huì)去調(diào)用old,直到匹配為止。

1.functionaddMethod(object,name,f)

2.{

3.varold=object[name];

4.object[name]=function()

5.{

6.//f.length為函數(shù)定義時(shí)的參數(shù)個(gè)數(shù)

7.//arguments.length為函數(shù)調(diào)用時(shí)的參數(shù)個(gè)數(shù)

8.if(f.length===arguments.length)

9.{

10.returnf.apply(this,arguments);

11.}

12.elseif(typeofold==="function")

13.{

14.returnold.apply(this,arguments);

15.}

16.};

17.}

18.

19.

20.//不傳參數(shù)時(shí),返回所有name

21.functionfind0()

22.{

23.returnthis.names;

24.}

25.

26.

27.//傳一個(gè)參數(shù)時(shí),返回firstName匹配的name

28.functionfind1(firstName)

29.{

30.varresult=[];

31.for(vari=0;i

32.{

33.if(this.names[i].indexOf(firstName)===0)

34.{

35.result.push(this.names[i]);

36.}

37.}

38.returnresult;

39.}

40.

41.

42.//傳兩個(gè)參數(shù)時(shí),返回firstName和lastName都匹配的name

43.functionfind2(firstName,lastName)

44.{

45.varresult=[];

46.for(vari=0;i

47.{

48.if(this.names[i]===(firstName+""+lastName))

49.{

50.result.push(this.names[i]);

51.}

52.}

53.returnresult;

54.}

55.

56.

57.varpeople={

58.names:["DeanEdwards","AlexRussell","DeanTom"]

59.};

60.

61.

62.addMethod(people,"find",find0);

63.addMethod(people,"find",find1);

64.addMethod(people,"find",find2);

65.

66.

67.console.log(people.find());//輸出["DeanEdwards","AlexRussell","DeanTom"]

68.console.log(people.find("Dean"));//輸出["DeanEdwards","DeanTom"]

69.console.log(people.find("Dean","Edwards"));//輸出["DeanEdwards"]

以上就是小編今天為大家分享的關(guān)于Web前端工程師應(yīng)該知道的JavaScript的10個(gè)難點(diǎn)。希望本篇文章能夠?qū)φ趶氖耊eb前端學(xué)習(xí)的小伙伴們有所幫助。想要了解更多web前端相關(guān)知識(shí)記得關(guān)注北大青鳥(niǎo)Web培訓(xùn)官網(wǎng)最后祝愿小伙伴們工作順利!

原文鏈接:#/a/1190000010371988

Web前端工程師應(yīng)該知道的提高JavaScript技能的技巧!

今天小編要跟大家分享的文章是關(guān)于Web前端工程師應(yīng)該知道的提高JavaScript

技能的技巧!熟悉web前端工作的小伙伴都知道,JavaScript是前端工程師的必備技能。JavaScript

是一種復(fù)雜的語(yǔ)言。如果是你是高級(jí)或者初級(jí)web開(kāi)發(fā)人員,了解它的基本概念非常重要。本篇文章小編就為大家介紹幾種提高JavaScript

技能的技巧,下面讓我們一起來(lái)看一看吧!

01、變量賦值(值vs引用)

理解JavaScript如何給變量賦值可以幫助我們減少一些不必要的bug。如果你不理解這一點(diǎn),可能很容易地編寫被無(wú)意中更改值的代碼。

JavaScript總是按照值來(lái)給變量賦值。這一部分非常重要:當(dāng)指定的值是JavaScript的五種基本類型之一(即

Boolean,null,undefined,String和Number)時(shí),將分配實(shí)際值。但是,當(dāng)指定的值是

Array,F(xiàn)unction或Object時(shí),將分配對(duì)內(nèi)存中對(duì)象的引用給變量。

在以下代碼段中,使用var1對(duì)var2進(jìn)行賦值。由于var1是基本類型(String),因此var2的值等于var1的String

值,并且可以認(rèn)為此時(shí)與var1完全不同。因此,重新賦值var2對(duì)var1沒(méi)有影響。

letvar1='Mystring';

letvar2=var1;

var2='Mynewstring';

console.log(var1);

//'Mystring'

console.log(var2);

//'Mynewstring'

接著,與對(duì)象賦值進(jìn)行比較。

letvar1={name:'Jim'}

letvar2=var1;

var2.name='John';

console.log(var1);

//{name:'John'}

console.log(var2);

//{name:'John'}

如果你期望它會(huì)像原始類型賦值那樣,很可能會(huì)出問(wèn)題!如果你創(chuàng)建了一個(gè)無(wú)意中會(huì)改變對(duì)象的函數(shù),就會(huì)出現(xiàn)一些非預(yù)期的行為。

02、閉包

閉包是一個(gè)重要的JavaScript模式,可以私有訪問(wèn)變量。在本例中,createGreeter返回一個(gè)匿名函數(shù),這個(gè)函數(shù)可以訪問(wèn)參數(shù)

greeting(在這里是“Hello”)。在后續(xù)的調(diào)用中,sayHello將有權(quán)訪問(wèn)這個(gè)greeting!

functioncreateGreeter(greeting){

returnfunction(name){

console.log(greeting+','+name);

}

}

constsayHello=createGreeter('Hello');

sayHello('Joe');

//Hello,Joe

在更真實(shí)的場(chǎng)景中,你可以設(shè)想一個(gè)初始函數(shù)apiConnect(apiKey),它返回一些使用APIkey的方法。在這種情況下,apiKey

只需要提供一次即可。

functionapiConnect(apiKey){

functionget(route){

returnfetch(`${route}?key=${apiKey}`);

}

functionpost(route,params){

returnfetch(route,{

method:'POST',

body:JSON.stringify(params),

headers:{

'Authorization':`Bearer${apiKey}`

}

})

}

return{get,post}

}

constapi=apiConnect('my-secret-key');

//NoneedtoincludetheapiKeyanymore

api.get('#/get-endpoint');

api.post('#/post-endpoint',{name:'Joe'});

03、解構(gòu)

JavaScript參數(shù)解構(gòu)可以從對(duì)象中干中提取所需屬性的常用方法。

constobj={

ame:'Joe',

food:'cake'

}

const{name,food}=obj;

console.log(name,food);

//'Joe''cake'

如果要以其他名稱提取屬性,可以使用如下方式:

constobj={

ame:'Joe',

food:'cake'

}

const{name:myName,food:myFood}=obj;

console.log(myName,myFood);

//'Joe''cake'

解構(gòu)經(jīng)常也用于直接用于提取傳給函數(shù)的參數(shù)。如果你熟悉React,可能已經(jīng)見(jiàn)過(guò)這個(gè):

constperson={

ame:'Eddie',

age:24

}

functionintroduce({name,age}){

console.log(`I'm${name}andI'm${age}yearsold!`);

}

console.log(introduce(person));

//"I'mEddieandI'm24yearsold!"

04、展開(kāi)運(yùn)算

ES6的一個(gè)常用之一的特性就是展開(kāi)(...)運(yùn)算符了,在下面的例子中,Math.max不能應(yīng)用于arr

數(shù)組,因?yàn)樗粚?shù)組作為參數(shù),但它可以將各個(gè)元素作為參數(shù)傳入。展開(kāi)運(yùn)算符...可用于提取數(shù)組的各個(gè)元素。

constarr=[4,6,-1,3,10,4];

constmax=Math.max(...arr);

console.log(max);

//10

05、剩余參數(shù)

剩余參數(shù)語(yǔ)法和展開(kāi)語(yǔ)法看起來(lái)的一樣的,不同的是展開(kāi)語(yǔ)法是為了結(jié)構(gòu)數(shù)組和對(duì)象;而剩余參數(shù)和展開(kāi)運(yùn)算符是相反的,剩余參數(shù)收集多個(gè)元素合成一個(gè)數(shù)組。

functionmyFunc(...args){

console.log(args[0]+args[1]);

}

myFunc(1,2,3,4);

//3

restparameters和arguments的區(qū)別

1.arguments是偽數(shù)組,包含所有的實(shí)參

2.剩余參數(shù)是標(biāo)準(zhǔn)的數(shù)組,可以使用數(shù)組的方法

06、數(shù)組方法

JavaScript數(shù)組方法通常可以提供令人難以置信的、優(yōu)雅的方法來(lái)執(zhí)行所需的數(shù)據(jù)轉(zhuǎn)換。作為StackOverflow

的貢獻(xiàn)者,我經(jīng)常看到關(guān)于如何以某種方式操縱對(duì)象數(shù)組的問(wèn)題,這往往也是數(shù)組方法的完美用例。

map、filter、reduce

JavaScript數(shù)組方法map、filter和reduce容易混淆,這些都是轉(zhuǎn)換數(shù)組或返回聚合值的有用方法。

map:返回一個(gè)數(shù)組,其中每個(gè)元素都使用指定函數(shù)進(jìn)行過(guò)轉(zhuǎn)換。

constarr=[1,2,3,4,5,6];

constmapped=arr.map(el=el+20);

console.log(mapped);

//[21,22,23,24,25,26]

filter:返回一個(gè)數(shù)組,只有當(dāng)指定函數(shù)返回true時(shí),相應(yīng)的元素才會(huì)被包含在這個(gè)數(shù)組中。

constarr=[1,2,3,4,5,6];

constfiltered=arr.filter(el=el===2||el===4);

console.log(filtered);

//[2,4]

reduce:按函數(shù)中指定的值累加

constarr=[1,2,3,4,5,6];

constreduced=arr.reduce((total,current)=total+current);

console.log(reduced);

//21

find,findIndex,indexOf

find:返回與指定條件匹配的第一個(gè)實(shí)例,如果查到不會(huì)繼續(xù)查找其他匹配的實(shí)例。

constarr=[1,2,3,4,5,6,7,8,9,10];

constfound=arr.find(el=el5);

console.log(found);

//6

再次注意,雖然5之后的所有元素都滿足條件,但是只返回第一個(gè)匹配的元素。當(dāng)你發(fā)現(xiàn)匹配項(xiàng)時(shí),通常會(huì)中斷for循環(huán),在這種情況下,這實(shí)際上非常有用。

findIndex:這與find幾乎完全相同,但不是返回第一個(gè)匹配元素,而是返回第一個(gè)匹配元素的索引。

constarr=['Nick','Frank','Joe','Frank'];

constfoundIndex=arr.findIndex(el=el==='Frank');

console.log(foundIndex);

//1

indexOf:與findIndex幾乎完全相同,但它不是將函數(shù)作為參數(shù),而是采用一個(gè)簡(jiǎn)單的值。

當(dāng)w你需要更簡(jiǎn)單的邏輯并且不需要使用函數(shù)來(lái)檢查是否存在匹配時(shí),可以使用此方法。

constarr=['Nick','Frank','Joe','Frank'];

constfoundIndex=arr.indexOf('Frank');

console.log(foundIndex);

//1

push,pop,shift,unshift

push:這是一個(gè)相對(duì)簡(jiǎn)單的方法,它將一個(gè)項(xiàng)添加到數(shù)組的末尾。它就地修改數(shù)組,函數(shù)本身會(huì)返回添加到數(shù)組中的項(xiàng)。

letarr=[1,2,3,4];

constpushed=arr.push(5);

console.log(arr);

//[1,2,3,4,5]

console.log(pushed);

//5

pop:這將從數(shù)組中刪除最后一項(xiàng)。同樣,它在適當(dāng)?shù)奈恢眯薷臄?shù)組,函數(shù)本身返回從數(shù)組中刪除的項(xiàng)。

letarr=[1,2,3,4];

constpopped=arr.pop();

console.log(arr);

//[1,2,3]

console.log(popped);

//4

shift:從數(shù)組中刪除第一項(xiàng)。同樣,它在適當(dāng)?shù)奈恢眯薷臄?shù)組。函數(shù)本身返回從數(shù)組中刪除的項(xiàng)。

letarr=[1,2,3,4];

constshifted=arr.shift();

console.log(arr);

//[2,3,4]

console.log(shifted);

//1

unshift:將一個(gè)或多個(gè)元素添加到數(shù)組的開(kāi)頭。同樣,它在適當(dāng)?shù)奈恢眯薷臄?shù)組。與許多其他方法不同,函數(shù)本身返回?cái)?shù)組的新長(zhǎng)度。

letarr=[1,2,3,4];

constunshifted=arr.unshift(5,6,7);

console.log(arr);

//[5,6,7,1,2,3,4]

console.log(unshifted);

//7

splice,slice

splice:通過(guò)刪除或替換現(xiàn)有元素和/或添加新元素來(lái)更改數(shù)組的內(nèi)容,此方法會(huì)修改了數(shù)組本身。

下面的代碼示例的意思是:在數(shù)組的位置1上刪除0個(gè)元素,并插入b。

letarr=['a','c','d','e'];

arr.splice(1,0,'b')

slice:從指定的起始位置和指定的結(jié)束位置之前返回?cái)?shù)組的淺拷貝。如果未指定結(jié)束位置,則返回?cái)?shù)組的其余部分。

重要的是,此方法不會(huì)修改數(shù)組,而是返回所需的子集。

letarr=['a','b','c','d','e'];

constsliced=arr.slice(2,4);

console.log(sliced);

//['c','d']

console.log(arr);

//['a','b','c','d','e']

sort

sort:根據(jù)提供的函數(shù)對(duì)數(shù)組進(jìn)行排序。這個(gè)方法就地修改數(shù)組。如果函數(shù)返回負(fù)數(shù)或0,則順序保持不變。如果返回正數(shù),則交換元素順序。

letarr=[1,7,3,-1,5,7,2];

constsorter=(firstEl,secondEl)=firstEl-secondEl;

arr.sort(sorter);

console.log(arr);

//[-1,1,2,3,5,7,7]

07、Generators(生成器)

生成器是一種特殊的行為,實(shí)際上是一種設(shè)計(jì)模式,我們通過(guò)調(diào)用next()方法來(lái)遍歷一組有序的值。想象一下,例如使用遍歷器對(duì)數(shù)組[1,2,3,4,5]進(jìn)行遍歷。第一次調(diào)用next()方法返回1,第二次調(diào)用next()方法返回2,以此類推。當(dāng)數(shù)組中的所有值都返回后,調(diào)用next()方法將返回null或false或其它可能的值用來(lái)表示數(shù)組中的所有元素都已遍歷完畢。

function*greeter(){

yield'Hi';

yield'Howareyou?';

yield'Bye';

}

constgreet=greeter();

console.log(greet.next().value);

//'Hi'

console.log(greet.next().value);

//'Howareyou?'

console.log(greet.next().value);

//'Bye'

console.log(greet.next().value);

//undefined

使用生成器生成無(wú)限個(gè)值:

function*idCreator(){

leti=0;

while(true)

yieldi++;

}

constids=idCreator();

console.log(ids.next().value);

//0

console.log(ids.next().value);

//1

console.log(ids.next().value);

//2

//etc...

08、恒等運(yùn)算符(===)與相等運(yùn)算符(==)

大家一定要知道JavaScript中的恒等運(yùn)算符(===)和相等運(yùn)算符(==)之間的區(qū)別!

==運(yùn)算符在比較值之前會(huì)進(jìn)行類型轉(zhuǎn)換,而===運(yùn)算符在比較之前不會(huì)進(jìn)行任何類型轉(zhuǎn)換。

console.log(0=='0');

//true

console.log(0==='0');

//false

09、對(duì)象比較

我看到JavaScript新手所犯的錯(cuò)誤是直接比較對(duì)象。變量指向內(nèi)存中對(duì)象的引用,而不是對(duì)象本身!實(shí)際比較它們的一種方法是將對(duì)象轉(zhuǎn)換為JSON

字符串。這有一個(gè)缺點(diǎn):對(duì)象屬性順序不能保證!比較對(duì)象的一種更安全的方法是引入專門進(jìn)行深度對(duì)象比較的庫(kù)(例如,lodash的isEqual)。

下面的對(duì)象看起來(lái)是相等的,但實(shí)際上它們指向不同的引用。

constjoe1={name:'Joe'};

constjoe2={name:'Joe'};

console.log(joe1===joe2);

//false

相反,下面的計(jì)算結(jié)果為true,因?yàn)橐粋€(gè)對(duì)象被設(shè)置為與另一個(gè)對(duì)象相等,因此指向相同的引用(內(nèi)存中只有一個(gè)對(duì)象)。

constjoe1={name:'Joe'};

constjoe2=joe1;

console.log(joe1===joe2);

//true

相反,以下計(jì)算結(jié)果為true,因?yàn)橐粋€(gè)對(duì)象設(shè)置為等于另一個(gè)對(duì)象,因此指向相同的引用(內(nèi)存中只有一個(gè)對(duì)象)。

constjoe1={name:'Joe'};

constjoe2=joe1;

console.log(joe1===joe2);

//true

10、回調(diào)函數(shù)

很多人都被JavaScript回調(diào)函數(shù)嚇倒了!他們很簡(jiǎn)單,舉個(gè)例子。console.log函數(shù)作為回調(diào)傳遞給myFunc。

它在setTimeout完成時(shí)執(zhí)行。

functionmyFunc(text,callback){

setTimeout(function(){

callback(text);

},2000);

}

myFunc('Helloworld!',console.log);

//'Helloworld!'

11、Promises

一旦你理解了JavaScript回調(diào),很快就會(huì)發(fā)現(xiàn)自己陷入了“回調(diào)地獄”中。這個(gè)時(shí)候可以使用promise,將異步邏輯包裝在promise

中,成功時(shí)resolve或在失敗時(shí)reject使用“then”來(lái)處理成功的情況,使用catch來(lái)處理異常。

constmyPromise=newPromise(function(res,rej){

setTimeout(function(){

if(Math.random()

returnres('Hooray!');

}

returnrej('Ohno!');

},1000);

});

myPromise

.then(function(data){

console.log('Success:'+data);

})

.catch(function(err){

console.log('Error:'+err);

});

//IfMath.random()returnslessthan0.9thefollowingislogged:

//"Success:Hooray!"

//IfMath.random()returns0.9orgreaterthefollowingislogged:

//"Error:Onno!"

12、Async/Await

在掌握了promise的用法后,你可能也會(huì)喜歡asyncawait,它只是一種基于promise

的“語(yǔ)法糖”。在下面的示例中,我們創(chuàng)建了一個(gè)async函數(shù),并awaitgreeterpromise。

constgreeter=newPromise((res,rej)={

setTimeout(()=res('Helloworld!'),2000);

})

asyncfuncti

網(wǎng)頁(yè)名稱:javascript工程,JavaScriPt
URL標(biāo)題:http://chinadenli.net/article36/dsdsjsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)企業(yè)網(wǎng)站制作建站公司企業(yè)建站商城網(wǎng)站微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)