精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

看完這幾道 JavaScript 面試題,讓你與考官對(duì)答如流(中)

開發(fā) 前端
IIFE或立即調(diào)用的函數(shù)表達(dá)式是在創(chuàng)建或聲明后將被調(diào)用或執(zhí)行的函數(shù)。創(chuàng)建IIFE的語法是,將function (){}包裹在在括號(hào)()內(nèi),然后再用另一個(gè)括號(hào)()調(diào)用它。

接上篇《看完這幾道 JavaScript 面試題,讓你與考官對(duì)答如流(上)

[[313262]]

26. 什么是 IIFE,它的用途是什么?

IIFE或立即調(diào)用的函數(shù)表達(dá)式是在創(chuàng)建或聲明后將被調(diào)用或執(zhí)行的函數(shù)。創(chuàng)建IIFE的語法是,將function (){}包裹在在括號(hào)()內(nèi),然后再用另一個(gè)括號(hào)()調(diào)用它,如:(function(){})()

  1. (function(){...}());(function(){...})();(functionnamed(params){...})();(()=>{});(function(global){...})(window);constutility=(function(){return{...}}) 

這些示例都是有效的IIFE。倒數(shù)第二個(gè)救命表明我們可以將參數(shù)傳遞給IIFE函數(shù)。最后一個(gè)示例表明,我們可以將IIFE的結(jié)果保存到變量中,以便稍后使用。

IIFE的一個(gè)主要作用是避免與全局作用域內(nèi)的其他變量命名沖突或污染全局命名空間,來個(gè)例子。

  1. <scriptsrcscriptsrc="https://cdnurl.com/somelibrary.js"></script> 

假設(shè)我們引入了一個(gè)omelibr.js的鏈接,它提供了一些我們?cè)诖a中使用的全局函數(shù),但是這個(gè)庫有兩個(gè)方法我們沒有使用:createGraph和drawGraph,因?yàn)檫@些方法都有bug。我們想實(shí)現(xiàn)自己的createGraph和drawGraph方法。

解決此問題的一種方法是直接覆蓋:

  1. <scriptsrcscriptsrc="https://cdnurl.com/somelibrary.js"></script><script>functioncreateGraph(){//createGraphlogichere}functiondrawGraph(){//drawGraphlogichere}</script> 

當(dāng)我們使用這個(gè)解決方案時(shí),我們覆蓋了庫提供給我們的那兩個(gè)方法。

另一種方式是我們自己改名稱:

  1. <scriptsrcscriptsrc="https://cdnurl.com/somelibrary.js"></script><script>functionmyCreateGraph(){//createGraphlogichere}functionmyDrawGraph(){//drawGraphlogichere}</script> 

當(dāng)我們使用這個(gè)解決方案時(shí),我們把那些函數(shù)調(diào)用更改為新的函數(shù)名。

還有一種方法就是使用IIFE:

  1. <scriptsrcscriptsrc="https://cdnurl.com/somelibrary.js"></script><script>constgraphUtility=(function(){functioncreateGraph(){//createGraphlogichere}functiondrawGraph(){//drawGraphlogichere}return{createGraph,drawGraph}})</script> 

在此解決方案中,我們要聲明了graphUtility 變量,用來保存IIFE執(zhí)行的結(jié)果,該函數(shù)返回一個(gè)包含兩個(gè)方法createGraph和drawGraph的對(duì)象。

IIFE 還可以用來解決一個(gè)常見的面試題:

  1. varli=document.querySelectorAll('.list-group>li');for(vari=0,len=li.length;i<len;i++){li[i].addEventListener('click',function(e){console.log(i);}) 

假設(shè)我們有一個(gè)帶有l(wèi)ist-group類的ul元素,它有5個(gè)li子元素。當(dāng)我們單擊單個(gè)li元素時(shí),打印對(duì)應(yīng)的下標(biāo)值。但在此外上述代碼不起作用,這里每次點(diǎn)擊 li 打印 i 的值都是5,這是由于閉包的原因。

閉包只是函數(shù)記住其當(dāng)前作用域,父函數(shù)作用域和全局作用域的變量引用的能力。當(dāng)我們?cè)谌肿饔糜騼?nèi)使用var關(guān)鍵字聲明變量時(shí),就創(chuàng)建全局變量i。因此,當(dāng)我們單擊li元素時(shí),它將打印5,因?yàn)檫@是稍后在回調(diào)函數(shù)中引用它時(shí)i的值。

使用 IIFE 可以解決此問題:

  1. varli=document.querySelectorAll('.list-group>li');for(vari=0,len=li.length;i<len;i++){(function(currentIndex){li[currentIndex].addEventListener('click',function(e){console.log(currentIndex);})})(i);} 

該解決方案之所以行的通,是因?yàn)镮IFE會(huì)為每次迭代創(chuàng)建一個(gè)新的作用域,我們捕獲i的值并將其傳遞給currentIndex參數(shù),因此調(diào)用IIFE時(shí),每次迭代的currentIndex值都是不同的。

27. Function.prototype.apply 方法的用途是什么?

apply() 方法調(diào)用一個(gè)具有給定this值的函數(shù),以及作為一個(gè)數(shù)組(或類似數(shù)組對(duì)象)提供的參數(shù)。

  1. constdetails={message:'HelloWorld!'};functiongetMessage(){returnthis.message;}getMessage.apply(details);//'HelloWorld!' 

call()方法的作用和 apply() 方法類似,區(qū)別就是call()方法接受的是參數(shù)列表,而apply()方法接受的是一個(gè)參數(shù)數(shù)組。

  1. constperson={name:"MarkoPolo"};functiongreeting(greetingMessage){return`${greetingMessage}${this.name}`;}greeting.apply(person,['Hello']);//"HelloMarkoPolo!" 

28. `Function.prototype.call` 方法的用途是什么?

call() 方法使用一個(gè)指定的 this 值和單獨(dú)給出的一個(gè)或多個(gè)參數(shù)來調(diào)用一個(gè)函數(shù)。

  1. constdetails={message:'HelloWorld!'};functiongetMessage(){returnthis.message;}getMessage.call(details);//'HelloWorld!' 

注意:該方法的語法和作用與 apply() 方法類似,只有一個(gè)區(qū)別,就是call() 方法接受的是一個(gè)參數(shù)列表,而 apply() 方法接受的是一個(gè)包含多個(gè)參數(shù)的數(shù)組。

  1. constperson={name:"MarkoPolo"};functiongreeting(greetingMessage){return`${greetingMessage}${this.name}`;}greeting.call(person,'Hello');//"HelloMarkoPolo!" 

29. Function.prototype.apply 和 Function.prototype.call 之間有什么區(qū)別?

apply()方法可以在使用一個(gè)指定的 this 值和一個(gè)參數(shù)數(shù)組(或類數(shù)組對(duì)象)的前提下調(diào)用某個(gè)函數(shù)或方法。call()方法類似于apply(),不同之處僅僅是call()接受的參數(shù)是參數(shù)列表。

  1. constobj1={result:0};constobj2={result:0};functionreduceAdd(){letresult=0;for(leti=0,len=arguments.length;i<len;i++){result+=arguments[i];}this.result=result;}reduceAdd.apply(obj1,[1,2,3,4,5]);//15reduceAdd.call(obj2,1,2,3,4,5);//15 

30. Function.prototype.bind 的用途是什么?

bind() 方法創(chuàng)建一個(gè)新的函數(shù),在 bind() 被調(diào)用時(shí),這個(gè)新函數(shù)的this 被指定為 bind() 的第一個(gè)參數(shù),而其余參數(shù)將作為新函數(shù)的參數(shù),供調(diào)用時(shí)使用。

  1. importReactfrom'react';classMyComponentextendsReact.Component{constructor(props){super(props);this.state={value:""}thisthis.handleChange=this.handleChange.bind(this);//將“handleChange”方法綁定到“MyComponent”組件}handleChange(e){//dosomethingamazinghere}render(){return(<><inputtypeinputtype={this.props.type}value={this.state.value}onChange={this.handleChange}/></>)}} 

31. 什么是函數(shù)式編程? JavaScript 的哪些特性使其成為函數(shù)式語言的候選語言?

函數(shù)式編程(通常縮寫為FP)是通過編寫純函數(shù),避免共享狀態(tài)、可變數(shù)據(jù)、副作用 來構(gòu)建軟件的過程。數(shù)式編程是聲明式 的而不是命令式 的,應(yīng)用程序的狀態(tài)是通過純函數(shù)流動(dòng)的。與面向?qū)ο缶幊绦纬蓪?duì)比,面向?qū)ο笾袘?yīng)用程序的狀態(tài)通常與對(duì)象中的方法共享和共處。

函數(shù)式編程是一種編程范式 ,這意味著它是一種基于一些基本的定義原則(如上所列)思考軟件構(gòu)建的方式。當(dāng)然,編程范示的其他示例也包括面向?qū)ο缶幊毯瓦^程編程。

函數(shù)式的代碼往往比命令式或面向?qū)ο蟮拇a更簡潔,更可預(yù)測,更容易測試 - 但如果不熟悉它以及與之相關(guān)的常見模式,函數(shù)式的代碼也可能看起來更密集雜亂,并且 相關(guān)文獻(xiàn)對(duì)新人來說是不好理解的。

JavaScript支持閉包和高階函數(shù)是函數(shù)式編程語言的特點(diǎn)。

32. 什么是高階函數(shù)?

高階函數(shù)只是將函數(shù)作為參數(shù)或返回值的函數(shù)。

  1. functionhigherOrderFunction(param,callback){returncallback(param);} 

33. 為什么函數(shù)被稱為一等公民?

在JavaScript中,函數(shù)不僅擁有一切傳統(tǒng)函數(shù)的使用方式(聲明和調(diào)用),而且可以做到像簡單值一樣賦值(var func = function(){})、傳參(function func(x,callback){callback();})、返回(function(){return function(){}}),這樣的函數(shù)也稱之為第一級(jí)函數(shù)(First-class Function)。不僅如此,JavaScript中的函數(shù)還充當(dāng)了類的構(gòu)造函數(shù)的作用,同時(shí)又是一個(gè)Function類的實(shí)例(instance)。這樣的多重身份讓JavaScript的函數(shù)變得非常重要。

34. 手動(dòng)實(shí)現(xiàn) `Array.prototype.map 方法`

map() 方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果。

  1. functionmap(arr,mapCallback){//首先,檢查傳遞的參數(shù)是否正確。if(!Array.isArray(arr)||!arr.length||typeofmapCallback!=='function'){return[];}else{letresult=[];//每次調(diào)用此函數(shù)時(shí),我們都會(huì)創(chuàng)建一個(gè)result數(shù)組//因?yàn)槲覀儾幌敫淖冊(cè)紨?shù)組。for(leti=0,len=arr.length;i<len;i++){result.push(mapCallback(arr[i],i,arr));//將mapCallback返回的結(jié)果push到result數(shù)組中}returnresult;}} 

35. 手動(dòng)實(shí)現(xiàn)`Array.prototype.filter`方法

filter() 方法創(chuàng)建一個(gè)新數(shù)組, 其包含通過所提供函數(shù)實(shí)現(xiàn)的測試的所有元素。

  1. functionfilter(arr,filterCallback){//首先,檢查傳遞的參數(shù)是否正確。if(!Array.isArray(arr)||!arr.length||typeoffilterCallback!=='function'){return[];}else{letresult=[];//每次調(diào)用此函數(shù)時(shí),我們都會(huì)創(chuàng)建一個(gè)result數(shù)組//因?yàn)槲覀儾幌敫淖冊(cè)紨?shù)組。for(leti=0,len=arr.length;i<len;i++){//檢查filterCallback的返回值是否是真值if(filterCallback(arr[i],i,arr)){//如果條件為真,則將數(shù)組元素push到result中result.push(arr[i]);}}returnresult;//returntheresultarray}} 

36. 手動(dòng)實(shí)現(xiàn)`Array.prototype.reduce`方法

reduce() 方法對(duì)數(shù)組中的每個(gè)元素執(zhí)行一個(gè)由您提供的reducer函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個(gè)返回值。

  1. functionreduce(arr,reduceCallback,initialValue){//首先,檢查傳遞的參數(shù)是否正確。if(!Array.isArray(arr)||!arr.length||typeofreduceCallback!=='function'){return[];}else{//如果沒有將initialValue傳遞給該函數(shù),我們將使用第一個(gè)數(shù)組項(xiàng)作為initialValueinitialValuelethasInitialValue=initialValue!==undefined;letvalue=hasInitialValue?initialValue:arr[0];、//如果有傳遞initialValue,則索引從1開始,否則從0開始for(leti=hasInitialValue?0:1,len=arr.length;i<len;i++){value=reduceCallback(value,arr[i],i,arr);}returnvalue;}} 

37. arguments 的對(duì)象是什么?

arguments對(duì)象是函數(shù)中傳遞的參數(shù)值的集合。它是一個(gè)類似數(shù)組的對(duì)象,因?yàn)樗幸粋€(gè)length屬性,我們可以使用數(shù)組索引表示法arguments[1]來訪問單個(gè)值,但它沒有數(shù)組中的內(nèi)置方法,如:forEach、reduce、filter和map。

我們可以使用Array.prototype.slice將arguments對(duì)象轉(zhuǎn)換成一個(gè)數(shù)組。

  1. functionone(){returnArray.prototype.slice.call(arguments);} 

注意:箭頭函數(shù)中沒有arguments對(duì)象。

  1. functionone(){returnarguments;}consttwo=function(){returnarguments;}constthree=functionthree(){returnarguments;}constfour=()=>arguments;four();//Throwsanerror-argumentsisnotdefined 

當(dāng)我們調(diào)用函數(shù)four時(shí),它會(huì)拋出一個(gè)ReferenceError: arguments is not defined error。使用rest語法,可以解決這個(gè)問題。

  1. constfour=(...args)=>args; 

這會(huì)自動(dòng)將所有參數(shù)值放入數(shù)組中。

38. 如何創(chuàng)建一個(gè)沒有 prototype(原型)的對(duì)象?

我們可以使用Object.create方法創(chuàng)建沒有原型的對(duì)象。

  1. consto1={};console.log(o1.toString());//[objectObject]consto2=Object.create(null);console.log(o2.toString());//throwsanerroro2.toStringisnotafunction 

39. 為什么在調(diào)用這個(gè)函數(shù)時(shí),代碼中的`b`會(huì)變成一個(gè)全局變量?

  1. functionmyFunc(){leta=b=0;}myFunc(); 

原因是賦值運(yùn)算符是從右到左的求值的。這意味著當(dāng)多個(gè)賦值運(yùn)算符出現(xiàn)在一個(gè)表達(dá)式中時(shí),它們是從右向左求值的。所以上面代碼變成了這樣:

  1. functionmyFunc(){leta=(b=0);}myFunc(); 

首先,表達(dá)式b = 0求值,在本例中b沒有聲明。因此,JS引擎在這個(gè)函數(shù)外創(chuàng)建了一個(gè)全局變量b,之后表達(dá)式b = 0的返回值為0,并賦給新的局部變量a。

我們可以通過在賦值之前先聲明變量來解決這個(gè)問題。

  1. functionmyFunc(){leta,b;a=b=0;}myFunc(); 

40. ECMAScript 是什么?

ECMAScript 是編寫腳本語言的標(biāo)準(zhǔn),這意味著JavaScript遵循ECMAScript標(biāo)準(zhǔn)中的規(guī)范變化,因?yàn)樗荍avaScript的藍(lán)圖。

ECMAScript 和 Javascript,本質(zhì)上都跟一門語言有關(guān),一個(gè)是語言本身的名字,一個(gè)是語言的約束條件

只不過發(fā)明JavaScript的那個(gè)人(Netscape公司),把東西交給了ECMA(European Computer Manufacturers Association),這個(gè)人規(guī)定一下他的標(biāo)準(zhǔn),因?yàn)楫?dāng)時(shí)有java語言了,又想強(qiáng)調(diào)這個(gè)東西是讓ECMA這個(gè)人定的規(guī)則,所以就這樣一個(gè)神奇的東西誕生了,這個(gè)東西的名稱就叫做ECMAScript。

javaScript = ECMAScript + DOM + BOM(自認(rèn)為是一種廣義的JavaScript)

ECMAScript說什么JavaScript就得做什么!

JavaScript(狹義的JavaScript)做什么都要問問ECMAScript我能不能這樣干!如果不能我就錯(cuò)了!能我就是對(duì)的!

——突然感覺JavaScript好沒有尊嚴(yán),為啥要搞個(gè)人出來約束自己,

那個(gè)人被創(chuàng)造出來也好委屈,自己被創(chuàng)造出來完全是因?yàn)橐s束JavaScript。

41. ES6或ECMAScript 2015有哪些新特性?

  • 箭頭函數(shù)
  • 模板字符串
  • 加強(qiáng)的對(duì)象字面量
  • 對(duì)象解構(gòu)
  • Promise
  • 生成器
  • 模塊
  • Symbol
  • 代理
  • Set
  • 函數(shù)默認(rèn)參數(shù)
  • rest 和展開
  • 塊作用域

42. `var`,`let`和`const`的區(qū)別是什么?

var聲明的變量會(huì)掛載在window上,而let和const聲明的變量不會(huì):

  1. vara=100;console.log(a,window.a);//10100100letb=10;console.log(b,window.b);//110undefinedconstc=1;console.log(c,window.c);//1undefined 

var聲明變量存在變量提升,let和const不存在變量提升:

  1. console.log(a);//undefined===>a已聲明還沒賦值,默認(rèn)得到undefined值vara=100;console.log(b);//報(bào)錯(cuò):b isnotdefined===>找不到b這個(gè)變量letb=10;console.log(c);//報(bào)錯(cuò):c isnotdefined===>找不到c這個(gè)變量constc=10

let和const聲明形成塊作用域

  1. if(1){vara=100;letb=10;}console.log(a);//100console.log(b)//報(bào)錯(cuò):b is not defined ===>找不到b這個(gè)變量-------------------------------------------------------------if(1){vara=100;constc=1;}console.log(a);//100console.log(c)//報(bào)錯(cuò):c is not defined ===>找不到c這個(gè)變量 

同一作用域下let和const不能聲明同名變量,而var可以

  1. vara=100;console.log(a);//10100vara=10;console.log(a);//10-------------------------------------leta=100;leta=10;//控制臺(tái)報(bào)錯(cuò):Identifier 'a' has already been declared ===>標(biāo)識(shí)符a已經(jīng)被聲明了。 

暫存死區(qū)

  1. vara=100;if(1){a=10;//在當(dāng)前塊作用域中存在a使用let/const聲明的情況下,給a賦值10時(shí),只會(huì)在當(dāng)前作用域找變量a,//而這時(shí),還未到聲明時(shí)候,所以控制臺(tái)Error:aisnotdefinedleta=1;} 

const

  1. /**  1、一旦聲明必須賦值,不能使用null占位。**  2、聲明后不能再修改**  3、如果聲明的是復(fù)合類型數(shù)據(jù),可以修改其屬性***/consta=100;constlist=[];list[0]=10;console.log(list);  //[10]constobj={a:100};obj.name='apple';obj.a=10000;console.log(obj);  //{a:10000,name:'apple'} 

43. 什么是箭頭函數(shù)?

箭頭函數(shù)表達(dá)式的語法比函數(shù)表達(dá)式更簡潔,并且沒有自己的this,arguments,super或new.target。箭頭函數(shù)表達(dá)式更適用于那些本來需要匿名函數(shù)的地方,并且它不能用作構(gòu)造函數(shù)。

  1. //ES5VersionvargetCurrentDate=function(){returnnewDate();}//ES6VersionconstgetCurrentDate=()=>newDate(); 

在本例中,ES5 版本中有function(){}聲明和return關(guān)鍵字,這兩個(gè)關(guān)鍵字分別是創(chuàng)建函數(shù)和返回值所需要的。在箭頭函數(shù)版本中,我們只需要()括號(hào),不需要 return 語句,因?yàn)槿绻覀冎挥幸粋€(gè)表達(dá)式或值需要返回,箭頭函數(shù)就會(huì)有一個(gè)隱式的返回。

  1. //ES5Versionfunctiongreet(name){return'Hello'+name+'!';}//ES6Versionconstgreet=(name)=>`Hello${name}`;constgreet2=name=>`Hello${name}`; 

我們還可以在箭頭函數(shù)中使用與函數(shù)表達(dá)式和函數(shù)聲明相同的參數(shù)。如果我們?cè)谝粋€(gè)箭頭函數(shù)中有一個(gè)參數(shù),則可以省略括號(hào)。

  1. constgetArgs=()=>argumentsconstgetArgs2=(...rest)=>rest 

箭頭函數(shù)不能訪問arguments對(duì)象。所以調(diào)用第一個(gè)getArgs函數(shù)會(huì)拋出一個(gè)錯(cuò)誤。相反,我們可以使用rest參數(shù)來獲得在箭頭函數(shù)中傳遞的所有參數(shù)。

  1. constdata={result:0,nums:[1,2,3,4,5],computeResult(){//這里的“this”指的是“data”對(duì)象constaddAll=()=>{returnthis.nums.reduce((total,cur)=>total+cur,0)};this.result=addAll();}}; 

箭頭函數(shù)沒有自己的this值。它捕獲詞法作用域函數(shù)的this值,在此示例中,addAll函數(shù)將復(fù)制computeResult 方法中的this值,如果我們?cè)谌肿饔糜蚵暶骷^函數(shù),則this值為 window 對(duì)象。

44. 什么是類?

類(class)是在 JS 中編寫構(gòu)造函數(shù)的新方法。它是使用構(gòu)造函數(shù)的語法糖,在底層中使用仍然是原型和基于原型的繼承。

  1. //ES5VersionfunctionPerson(firstName,lastName,age,address){this.firstName=firstName;this.lastName=lastName;this.age=age;this.address=address;}Person.self=function(){returnthis;}Person.prototype.toString=function(){return"[objectPerson]";}Person.prototype.getFullName=function(){returnthis.firstName+""+this.lastName;}//ES6VersionclassPerson{constructor(firstName,lastName,age,address){this.lastName=lastName;this.firstName=firstName;this.age=age;this.address=address;}staticself(){returnthis;}toString(){return"[objectPerson]";}getFullName(){return`${this.firstName}${this.lastName}`;}} 

重寫方法并從另一個(gè)類繼承。

  1. //ES5VersionEmployee.prototype=Object.create(Person.prototype);functionEmployee(firstName,lastName,age,address,jobTitle,yearStarted){Person.call(this,firstName,lastName,age,address);this.jobTitle=jobTitle;this.yearStarted=yearStarted;}Employee.prototype.describe=function(){return`Iam${this.getFullName()}andIhaveapositionof${this.jobTitle}andIstartedat${this.yearStarted}`;}Employee.prototype.toString=function(){return"[objectEmployee]";}//ES6VersionclassEmployeeextendsPerson{//Inheritsfrom"Person"classconstructor(firstName,lastName,age,address,jobTitle,yearStarted){super(firstName,lastName,age,address);this.jobTitle=jobTitle;this.yearStarted=yearStarted;}describe(){return`Iam${this.getFullName()}andIhaveapositionof${this.jobTitle}andIstartedat${this.yearStarted}`;}toString(){//Overridingthe"toString"methodof"Person"return"[objectEmployee]";}} 

所以我們要怎么知道它在內(nèi)部使用原型?

  1. classSomething{}functionAnotherSomething(){}constas=newAnotherSomething();consts=newSomething();console.log(typeofSomething);//"function"console.log(typeofAnotherSomething);//"function"console.log(as.toString());//"[objectObject]"console.log(as.toString());//"[objectObject]"console.log(as.toString===Object.prototype.toString);//trueconsole.log(s.toString===Object.prototype.toString);//true 

45. 什么是模板字符串?

模板字符串是在 JS 中創(chuàng)建字符串的一種新方法。我們可以通過使用反引號(hào)使模板字符串化。

  1. //ES5Versionvargreet='HiI\'mMark';//ES6Versionletgreet=`HiI'mMark`; 

在 ES5 中我們需要使用一些轉(zhuǎn)義字符來達(dá)到多行的效果,在模板字符串不需要這么麻煩:

  1. //ES5VersionvarlastWords='\n'+'I\n'+'Am\n'+'IronMan\n';//ES6VersionletlastWords=`IAmIronMan`; 

在ES5版本中,我們需要添加\n以在字符串中添加新行。在模板字符串中,我們不需要這樣做。

  1. //ES5Versionfunctiongreet(name){return'Hello'+name+'!';}//ES6Versionfunctiongreet(name){return`Hello${name}!`;} 

在 ES5 版本中,如果需要在字符串中添加表達(dá)式或值,則需要使用+運(yùn)算符。在模板字符串s中,我們可以使用${expr}嵌入一個(gè)表達(dá)式,這使其比 ES5 版本更整潔。

46. 什么是對(duì)象解構(gòu)?

對(duì)象析構(gòu)是從對(duì)象或數(shù)組中獲取或提取值的一種新的、更簡潔的方法。假設(shè)有如下的對(duì)象:

  1. constemployee={firstName:"Marko",lastName:"Polo",position:"SoftwareDeveloper",yearHired:2017}; 

從對(duì)象獲取屬性,早期方法是創(chuàng)建一個(gè)與對(duì)象屬性同名的變量。這種方法很麻煩,因?yàn)槲覀円獮槊總€(gè)屬性創(chuàng)建一個(gè)新變量。假設(shè)我們有一個(gè)大對(duì)象,它有很多屬性和方法,用這種方法提取屬性會(huì)很麻煩。

  1. varfirstName=employee.firstName;varlastName=employee.lastName;varposition=employee.position;varyearHired=employee.yearHired; 

使用解構(gòu)方式語法就變得簡潔多了:

  1. {firstName,lastName,position,yearHired}=employee; 

我們還可以為屬性取別名:

  1. let{firstName:fName,lastName:lName,position,yearHired}=employee; 

當(dāng)然如果屬性值為 undefined 時(shí),我們還可以指定默認(rèn)值:

  1. let{firstName="Mark",lastName:lName,position,yearHired}=employee; 

47. 什么是 ES6 模塊?

模塊使我們能夠?qū)⒋a基礎(chǔ)分割成多個(gè)文件,以獲得更高的可維護(hù)性,并且避免將所有代碼放在一個(gè)大文件中。在 ES6 支持模塊之前,有兩個(gè)流行的模塊。

  • CommonJS-Node.js
  • AMD(異步模塊定義)-瀏覽器

基本上,使用模塊的方式很簡單,import用于從另一個(gè)文件中獲取功能或幾個(gè)功能或值,同時(shí)export用于從文件中公開功能或幾個(gè)功能或值。

(1) 導(dǎo)出

使用 ES5 (CommonJS)

  1. //使用ES5CommonJS-helpers.jsexports.isNull=function(val){returnval===null;}exports.isUndefined=function(val){returnval===undefined;}exports.isNullOrUndefined=function(val){returnexports.isNull(val)||exports.isUndefined(val);} 

使用 ES6 模塊

  1. //使用ES6Modules-helpers.jsexportfunctionisNull(val){returnval===null;}exportfunctionisUndefined(val){returnval===undefined;}exportfunctionisNullOrUndefined(val){returnisNull(val)||isUndefined(val);} 

在另一個(gè)文件中導(dǎo)入函數(shù)

  1. //使用ES5(CommonJS)-index.jsconsthelpers=require('./helpers.js');//helpershelpersisanobjectconstisNull=helpers.isNull;constisUndefined=helpers.isUndefined;constisNullOrUndefined=helpers.isNullOrUndefined;//orifyourenvironmentsupportsDestructuringconst{isNull,isUndefined,isNullOrUndefined}=require('./helpers.js');-------------------------------------------------------//ES6Modules-index.jsimport*ashelpersfrom'./helpers.js';//helpersisanobject//orimport{isNull,isUndefined,isNullOrUndefinedasisValid}from'./helpers.js';//using"as"forrenamingnamedexports 

(2) 在文件中導(dǎo)出單個(gè)功能或默認(rèn)導(dǎo)出

使用 ES5 (CommonJS)

  1. //使用ES5(CommonJS)-index.jsclassHelpers{staticisNull(val){returnval===null;}staticisUndefined(val){returnval===undefined;}staticisNullOrUndefined(val){returnthis.isNull(val)||this.isUndefined(val);}}module.exports=Helpers

使用ES6 Modules

  1. //使用ES6Modules-helpers.jsclassHelpers{staticisNull(val){returnval===null;}staticisUndefined(val){returnval===undefined;}staticisNullOrUndefined(val){returnthis.isNull(val)||this.isUndefined(val);}}exportdefaultHelpers 

(3) 從另一個(gè)文件導(dǎo)入單個(gè)功能

使用ES5 (CommonJS)

  1. //使用ES5(CommonJS)-index.jsconstHelpers=require('./helpers.js');console.log(Helpers.isNull(null)); 

使用 ES6 Modules

  1. importHelpersfrom'.helpers.js'console.log(Helpers.isNull(null)); 

48. 什么是`Set`對(duì)象,它是如何工作的?

Set 對(duì)象允許你存儲(chǔ)任何類型的唯一值,無論是原始值或者是對(duì)象引用。

我們可以使用Set構(gòu)造函數(shù)創(chuàng)建Set實(shí)例。

  1. constset1=newSet();constset2=newSet(["a","b","c","d","d","e"]); 

我們可以使用add方法向Set實(shí)例中添加一個(gè)新值,因?yàn)閍dd方法返回Set對(duì)象,所以我們可以以鏈?zhǔn)降姆绞皆俅问褂胊dd。如果一個(gè)值已經(jīng)存在于Set對(duì)象中,那么它將不再被添加。

  1. set2.add("f");set2.add("g").add("h").add("i").add("j").add("k").add("k");//后一個(gè)“k”不會(huì)被添加到set對(duì)象中,因?yàn)樗呀?jīng)存在了 

我們可以使用has方法檢查Set實(shí)例中是否存在特定的值。

  1. set2.has("a")//trueset2.has("z")//true 

我們可以使用size屬性獲得Set實(shí)例的長度。

  1. set2.size//returns10 

可以使用clear方法刪除 Set 中的數(shù)據(jù)。

  1. set2.clear(); 

我們可以使用Set對(duì)象來刪除數(shù)組中重復(fù)的元素。

  1. constnumbers=[1,2,3,4,5,6,6,7,8,8,5];constuniqueNums=[...newSet(numbers)];//[1,2,3,4,5,6,7,8] 

49. 什么是回調(diào)函數(shù)?

回調(diào)函數(shù)是一段可執(zhí)行的代碼段,它作為一個(gè)參數(shù)傳遞給其他的代碼,其作用是在需要的時(shí)候方便調(diào)用這段(回調(diào)函數(shù))代碼。

在JavaScript中函數(shù)也是對(duì)象的一種,同樣對(duì)象可以作為參數(shù)傳遞給函數(shù),因此函數(shù)也可以作為參數(shù)傳遞給另外一個(gè)函數(shù),這個(gè)作為參數(shù)的函數(shù)就是回調(diào)函數(shù)。

  1. constbtnAdd=document.getElementById('btnAdd');btnAdd.addEventListener('click',functionclickCallback(e){//dosomethinguseless}); 

在本例中,我們等待id為btnAdd的元素中的click事件,如果它被單擊,則執(zhí)行clickCallback函數(shù)。回調(diào)函數(shù)向某些數(shù)據(jù)或事件添加一些功能。

數(shù)組中的reduce、filter和map方法需要一個(gè)回調(diào)作為參數(shù)。回調(diào)的一個(gè)很好的類比是,當(dāng)你打電話給某人,如果他們不接,你留下一條消息,你期待他們回調(diào)。調(diào)用某人或留下消息的行為是事件或數(shù)據(jù),回調(diào)是你希望稍后發(fā)生的操作。

50. Promise 是什么?

Promise 是異步編程的一種解決方案:從語法上講,promise是一個(gè)對(duì)象,從它可以獲取異步操作的消息;從本意上講,它是承諾,承諾它過一段時(shí)間會(huì)給你一個(gè)結(jié)果。promise有三種狀態(tài):pending(等待態(tài)),fulfiled(成功態(tài)),rejected(失敗態(tài));狀態(tài)一旦改變,就不會(huì)再變。創(chuàng)造promise實(shí)例后,它會(huì)立即執(zhí)行。

  1. fs.readFile('somefile.txt',function(e,data){if(e){console.log(e);}console.log(data);}); 

如果我們?cè)诨卣{(diào)內(nèi)部有另一個(gè)異步操作,則此方法存在問題。我們將有一個(gè)混亂且不可讀的代碼。此代碼稱為“回調(diào)地獄”。

  1. //回調(diào)地獄fs.readFile('somefile.txt',function(e,data){//yourcodeherefs.readdir('directory',function(e,files){//yourcodeherefs.mkdir('directory',function(e){//yourcodehere})})}) 

如果我們?cè)谶@段代碼中使用promise,它將更易于閱讀、理解和維護(hù)。

  1. promReadFile('file/path').then(data=>{returnpromReaddir('directory');}).then(data=>{returnpromMkdir('directory');}).catch(e=>{console.log(e);}) 

promise有三種不同的狀態(tài):

  • pending:初始狀態(tài),完成或失敗狀態(tài)的前一個(gè)狀態(tài)
  • fulfilled:操作成功完成
  • rejected:操作失敗

pending 狀態(tài)的 Promise 對(duì)象會(huì)觸發(fā) fulfilled/rejected 狀態(tài),在其狀態(tài)處理方法中可以傳入?yún)?shù)/失敗信息。當(dāng)操作成功完成時(shí),Promise 對(duì)象的 then 方法就會(huì)被調(diào)用;否則就會(huì)觸發(fā) catch。如:

  1. constmyFirstPromise=newPromise((resolve,reject)=>{setTimeout(function(){resolve("成功!");},250);});myFirstPromise.then((data)=>{console.log("Yay!"+data);}).catch((e)=>{...}); 

由于篇幅過長,我將此系列分成上中下三篇,下篇我們?cè)谝姟?/p>

責(zé)任編輯:趙寧寧 來源: 今日頭條
相關(guān)推薦

2020-01-13 07:50:58

JavaScript開發(fā)

2023-04-10 14:57:57

AI復(fù)活逝者

2021-02-26 05:20:42

Java參數(shù)化泛型

2019-07-18 15:42:53

Redisoffer數(shù)據(jù)庫

2024-03-07 07:37:03

AQS線程獨(dú)占鎖

2022-03-31 09:50:45

JS面試題

2019-12-26 09:52:33

Redis集群線程

2023-09-04 08:28:34

JavaScripforEach 循環(huán)

2013-01-05 14:51:34

JavaScriptjQuery面試

2024-06-04 14:52:28

2020-04-20 13:11:21

HashMap底層存儲(chǔ)

2023-11-15 07:54:03

HashMap數(shù)據(jù)結(jié)構(gòu)

2024-03-04 00:25:00

機(jī)器人GPT-4

2024-07-09 13:47:00

2020-09-25 15:40:22

toStringvalueOf前端

2019-09-10 10:48:10

RedisJava面試題

2019-08-13 08:43:07

JavaScript前端面試題

2021-05-08 14:20:27

Redis面試數(shù)據(jù)庫

2022-05-04 23:09:33

TS交叉運(yùn)算工具

2020-04-29 09:30:48

Google面試題工程師
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩电影网址| 91日韩中文字幕| 91成人在线| 亚洲国产精品激情在线观看| 成人欧美在线视频| 亚洲一区二区91| 第一sis亚洲原创| 日韩欧美的一区二区| 国产女女做受ⅹxx高潮| 成人在线免费看黄| 久久久精品影视| 91亚洲永久免费精品| 久久中文字幕免费| 亚洲天堂免费| 在线精品国产欧美| 稀缺小u女呦精品呦| 久久亚洲精品人成综合网| 亚洲成人动漫精品| 中文字幕色一区二区| 亚洲aⅴ在线观看| 久色婷婷小香蕉久久| 欧美一级片在线播放| 欧美a级片免费看| 爽爽窝窝午夜精品一区二区| 日韩精品综合一本久道在线视频| 波多野结衣家庭教师视频| 宅男网站在线免费观看| 国产欧美日本一区二区三区| 国产在线精品一区二区中文| 国产免费一区二区三区免费视频| 每日更新成人在线视频| 久久久久久久一区二区三区| 三级黄色在线观看| 欧美午夜精彩| 亚洲视频在线免费观看| avtt香蕉久久| 欧美亚洲色图校园春色| 日韩精品一区二区三区三区免费 | 污污内射在线观看一区二区少妇| 国产亚洲人成a在线v网站 | 色综合视频一区中文字幕| 亚洲精品天堂网| 欧美日韩有码| 国产亚洲精品日韩| 欧美多人猛交狂配| 亚洲性视频大全| 亚洲久久久久久久久久| 欧美肉大捧一进一出免费视频| 最新精品在线| 日韩精品一区二区三区视频播放| 中文字幕人妻熟女人妻a片| 高清一区二区三区av| 欧美人体做爰大胆视频| 高清av免费看| 一区二区三区无毛| 在线播放91灌醉迷j高跟美女| 日韩高清第一页| 国产精品美女久久久久人| 正在播放亚洲一区| 亚洲综合123| 欧美一区一区| 精品久久久久一区| 亚洲自拍偷拍精品| 自拍偷拍一区| 日韩中文字幕免费看| 波兰性xxxxx极品hd| 91九色精品| 欧美成人免费大片| 日韩精品无码一区二区| 国产欧美短视频| 国产成人中文字幕| 91九色蝌蚪91por成人| 国产一区二区三区香蕉| 国产传媒一区二区三区| 欧美新色视频| 国产精品女同一区二区三区| 二级片在线观看| 国语对白在线刺激| 欧美网站在线观看| 奇米视频888| 99a精品视频在线观看| 亚洲精品福利在线观看| www亚洲色图| 一区二区三区四区日韩| 97精品国产97久久久久久| 麻豆成人免费视频| 国内精品视频一区二区三区八戒| 高清国产在线一区| 国产原创av在线| 亚洲精品日日夜夜| 99热成人精品热久久66| 国产精品毛片无码| 亚洲欧美精品一区二区| 国产精品嫩草影院俄罗斯| 亚洲韩日在线| 国产精品一区专区欧美日韩| 亚洲免费视频网| 欧美国产国产综合| 国产美女主播在线播放| 国产香蕉久久| 日韩精品久久久久久福利| 欧美激情精品久久久久久免费| 1024成人| 亚洲a在线播放| 国产乱子伦三级在线播放| 亚洲国产wwwccc36天堂| 一级黄色特级片| 日本成人a网站| 久久艳片www.17c.com| 狠狠人妻久久久久久| 国产精品中文有码| 亚洲国产日韩综合一区| 久草免费在线视频| 欧美一级欧美一级在线播放| 欧美人与性囗牲恔配| 精品91视频| 国产欧美一区二区白浆黑人| 视频一区二区三区在线看免费看| 亚洲精品videosex极品| 久久久久国产一区| 小说区图片区色综合区| 欧美极品少妇xxxxⅹ喷水| 一区二区www| 久久综合色8888| 亚洲精品久久久久久久蜜桃臀| 色综合久久久| 在线日韩av观看| 久久精品视频7| 99久久99久久久精品齐齐| 好吊色这里只有精品| www.久久.com| 国产亚洲精品久久久久久777| 国产一级在线观看视频| 国产伦精一区二区三区| 一区二区在线高清视频| 国产精成人品2018| 国产亚洲精品美女久久久| 香蕉影院在线观看| 91论坛在线播放| 浮妇高潮喷白浆视频| 开心激情综合| 97视频人免费观看| 五十路在线观看| 午夜一区二区三区视频| 欧美xxxxx精品| 日韩午夜电影| 欧美二区在线| 日韩电影免费观看高清完整版| 日韩精品中文字幕在线播放| 日韩字幕在线观看| av在线免费不卡| 久久黄色片视频| 日韩精品免费一区二区三区竹菊 | 国产乱国产乱300精品| 在线精品日韩| 高清一区二区三区av| 欧美成人精品在线播放| 成人午夜免费福利| 香蕉成人伊视频在线观看| 9.1成人看片| 日韩精品欧美精品| 伊人久久婷婷色综合98网| 免费视频成人| 欧美高清在线播放| 五月婷婷六月激情| 欧美在线观看视频在线| 91大神福利视频| 国产在线国偷精品产拍免费yy| 日本一区二区三区四区五区六区| 成人亚洲精品| 久久久欧美一区二区| 色视频精品视频在线观看| 欧美视频在线视频| 欧美成人久久久免费播放| 狠狠色狠狠色合久久伊人| 青青视频免费在线| 天海翼精品一区二区三区| 国产福利视频一区二区| 黄色免费网站在线| 亚洲精品久久久久久久久| 四虎成人在线观看| 亚洲免费色视频| 黄色国产在线观看| 美女爽到高潮91| 日韩极品视频在线观看| 久久av中文| 亚洲一区二区三区视频| 日本免费一区二区六区| 中文字幕av一区二区三区谷原希美| 国产精品玖玖玖| 岛国视频午夜一区免费在线观看| 91无套直看片红桃在线观看| 丁香一区二区三区| 九色porny91| 亚洲一级影院| 亚洲啪啪av| 久久中文资源| 91精品视频专区| 天堂√中文最新版在线| 久久九九精品99国产精品| 午夜视频福利在线| 欧美精品高清视频| 四虎成人永久免费视频| 亚洲精品国产无天堂网2021| 亚洲熟妇一区二区三区| 国产一区二区h| 自拍偷拍 国产| 亚洲大黄网站| 裸体裸乳免费看| 国产在视频线精品视频www666| 91免费看蜜桃| 国产第一亚洲| 欧美专区第一页| 色在线视频网| 日韩一区二区精品视频| 黄色av免费在线看| 亚洲国产美女精品久久久久∴| 在线观看国产精品入口男同| 色婷婷一区二区三区四区| 久久一级黄色片| 成人欧美一区二区三区| 亚洲黄色免费视频| 北岛玲一区二区三区四区| 天堂网成人在线| 视频一区二区三区入口| jizzjizz国产精品喷水| 亚洲精品国产日韩| 欧美乱做爰xxxⅹ久久久| 亚洲区综合中文字幕日日| 日本一区二区三区视频在线观看| 伊人久久大香线蕉| 久久香蕉综合色| 国产一区二区三区亚洲| 91pron在线| 自拍偷拍亚洲| 91久久在线观看| 日韩精品第二页| 国产日韩精品视频| 日本成人一区二区| 国产精品视频网址| 黄色成人在线观看网站| 国产精品一区二区在线| 国产成人精品一区二区三区免费| 国产成人一区二区三区小说| 婷婷激情一区| 国产精品久久久| 欧美日韩女优| 国产日韩精品在线观看| 欧美一区=区三区| 成人黄色免费片| 精品国产一区二区三区性色av| 91色在线视频| 精品视频在线一区| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | www五月天com| 色综合久久久久网| av首页在线观看| 精品视频1区2区3区| 一级成人免费视频| 日韩欧美国产一区二区在线播放 | 亚洲男人第一网站| 精品无人乱码| 日韩亚洲综合在线| 欧洲黄色一区| 日本一区二区三区在线播放 | 成人欧美一区二区三区在线观看| ccyy激情综合| 久久精品成人一区二区三区蜜臀| 妖精一区二区三区精品视频| 日韩性感在线| 女同性一区二区三区人了人一| 我的公把我弄高潮了视频| 性欧美精品高清| 在线黄色免费看| 成人污污视频在线观看| 自拍偷拍中文字幕| 亚洲欧洲日本在线| 日本在线观看视频网站| 色婷婷av一区二区三区之一色屋| 中文字幕欧美人妻精品| 日韩精品中午字幕| 国产中文字幕在线观看| 久久天天躁狠狠躁老女人| www.综合网.com| 国产精品露脸自拍| 国产乱人伦精品一区| 日韩高清av电影| 国内精品99| 99视频在线视频| 国产不卡视频一区| 日本二区在线观看| 亚洲精品videosex极品| 懂色av中文字幕| 精品日韩在线一区| fc2在线中文字幕| 久久噜噜噜精品国产亚洲综合 | 亚洲ⅴ国产v天堂a无码二区| 亚洲乱码中文字幕| 中文字幕国产在线观看| 欧美一区二区成人6969| 黄色av免费在线观看| 久久av红桃一区二区小说| 欧美艳星kaydenkross| 91嫩草免费看| 成人精品影院| 一区二区传媒有限公司| 国产成人鲁色资源国产91色综| 非洲一级黄色片| 午夜激情久久久| 99精品在线视频观看| 在线观看久久av| 久久青青视频| 国产视频在线观看一区| 国产精品久久天天影视| 不卡av免费在线| 91视视频在线直接观看在线看网页在线看| 麻豆精品国产免费| 欧美人动与zoxxxx乱| 狠狠狠综合7777久夜色撩人| 9.1国产丝袜在线观看| 亚洲精品不卡在线观看| 成年人免费观看的视频| 日本 国产 欧美色综合| 性少妇bbw张开| 精品久久久久久久久久国产| www日本高清| 欧美高清videos高潮hd| 色999久久久精品人人澡69| 任我爽在线视频精品一| 先锋影音国产一区| 91精品小视频| 精品久久香蕉国产线看观看gif| 国产综合无码一区二区色蜜蜜| 欧美成人h版在线观看| 亚洲午夜剧场| 异国色恋浪漫潭| 精品一区二区三区在线观看| 永久免费观看片现看| 在线观看国产精品网站| 国产一二三区在线视频| 国产成人在线亚洲欧美| 国产一区二区精品久| 欧美激情国产精品日韩| 99在线视频精品| 日韩欧美成人一区二区三区| 亚洲欧美在线免费观看| 校园春色亚洲色图| 任我爽在线视频精品一| 美美哒免费高清在线观看视频一区二区 | 一级一片免费看| 亚洲人成在线观看| av有声小说一区二区三区| 日韩欧美视频第二区| 麻豆一区二区三| 国产精品免费人成网站酒店| 欧美r级在线观看| 国产高清中文字幕在线| 久久精品国产一区二区三区日韩| 国产精品久久久久久模特| 一级黄色片大全| 欧美日韩高清一区| www视频在线免费观看| 国产乱码精品一区二区三区日韩精品 | 中文区中文字幕免费看| 精品国产自在精品国产浪潮| 国产精品99久久免费| 欧美乱大交xxxxx潮喷l头像| www国产成人| 91久久久久久久久久久久| 九色成人免费视频| 秋霞影视一区二区三区| 九热视频在线观看| 亚洲精品视频一区| 视频国产一区二区三区| 成人av电影天堂| 亚洲精品日本| 人妻无码一区二区三区免费| 日韩女优视频免费观看| 欧美91看片特黄aaaa| 成人手机视频在线| 91丝袜呻吟高潮美腿白嫩在线观看| 乱子伦一区二区三区| 欧美理论片在线观看| 西野翔中文久久精品国产| 日韩精品aaa| 欧美日韩在线看| 成a人片在线观看| 欧美高清一区二区| 国产美女主播视频一区| 日本视频在线观看免费| 久久手机免费视频| 国产欧美日韩精品高清二区综合区| 性chinese极品按摩| 亚洲乱码中文字幕综合| 都市激情一区| 国产一区在线观| 精品中文av资源站在线观看| 在线观看黄网站| 欧美老少配视频| 日本久久精品|