自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開(kāi)發(fā) 前端
IIFE或立即調(diào)用的函數(shù)表達(dá)式是在創(chuàng)建或聲明后將被調(diào)用或執(zhí)行的函數(shù)。創(chuàng)建IIFE的語(yǔ)法是,將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的語(yǔ)法是,將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)的其他變量命名沖突或污染全局命名空間,來(lái)個(gè)例子。

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

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

解決此問(wèn)題的一種方法是直接覆蓋:

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

當(dāng)我們使用這個(gè)解決方案時(shí),我們覆蓋了庫(kù)提供給我們的那兩個(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 變量,用來(lái)保存IIFE執(zhí)行的結(jié)果,該函數(shù)返回一個(gè)包含兩個(gè)方法createGraph和drawGraph的對(duì)象。

IIFE 還可以用來(lái)解決一個(gè)常見(jiàn)的面試題:

  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 可以解決此問(wèn)題:

  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ù)來(lái)調(diào)用一個(gè)函數(shù)。

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

注意:該方法的語(yǔ)法和作用與 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ù)式語(yǔ)言的候選語(yǔ)言?

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

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

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

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

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

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

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

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

在JavaScript中,函數(shù)不僅擁有一切傳統(tǒng)函數(shù)的使用方式(聲明和調(diào)用),而且可以做到像簡(jiǎn)單值一樣賦值(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ù)組, 其包含通過(guò)所提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素。

  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{//如果沒(méi)有將initialValue傳遞給該函數(shù),我們將使用第一個(gè)數(shù)組項(xiàng)作為initialValueinitialValuelethasInitialValue=initialValue!==undefined;letvalue=hasInitialValue?initialValue:arr[0];、//如果有傳遞initialValue,則索引從1開(kāi)始,否則從0開(kāi)始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]來(lái)訪問(wèn)單個(gè)值,但它沒(méi)有數(shù)組中的內(nèi)置方法,如:forEach、reduce、filter和map。

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

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

注意:箭頭函數(shù)中沒(méi)有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語(yǔ)法,可以解決這個(gè)問(wèn)題。

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

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

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

我們可以使用Object.create方法創(chuàng)建沒(méi)有原型的對(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沒(méi)有聲明。因此,JS引擎在這個(gè)函數(shù)外創(chuàng)建了一個(gè)全局變量b,之后表達(dá)式b = 0的返回值為0,并賦給新的局部變量a。

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

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

40. ECMAScript 是什么?

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

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

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

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

ECMAScript說(shuō)什么JavaScript就得做什么!

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

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

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

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

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

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已聲明還沒(méi)賦值,默認(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á)式的語(yǔ)法比函數(shù)表達(dá)式更簡(jiǎn)潔,并且沒(méi)有自己的this,arguments,super或new.target。箭頭函數(shù)表達(dá)式更適用于那些本來(lái)需要匿名函數(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ǔ)句,因?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ù)不能訪問(wèn)arguments對(duì)象。所以調(diào)用第一個(gè)getArgs函數(shù)會(huì)拋出一個(gè)錯(cuò)誤。相反,我們可以使用rest參數(shù)來(lái)獲得在箭頭函數(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ù)沒(méi)有自己的this值。它捕獲詞法作用域函數(shù)的this值,在此示例中,addAll函數(shù)將復(fù)制computeResult 方法中的this值,如果我們?cè)谌肿饔糜蚵暶骷^函數(shù),則this值為 window 對(duì)象。

44. 什么是類?

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

  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)建字符串的一種新方法。我們可以通過(guò)使用反引號(hào)使模板字符串化。

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

在 ES5 中我們需要使用一些轉(zhuǎn)義字符來(lái)達(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ù)組中獲取或提取值的一種新的、更簡(jiǎn)潔的方法。假設(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)方式語(yǔ)法就變得簡(jiǎn)潔多了:

  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(異步模塊定義)-瀏覽器

基本上,使用模塊的方式很簡(jiǎn)單,import用于從另一個(gè)文件中獲取功能或幾個(gè)功能或值,同時(shí)export用于從文件中公開(kāi)功能或幾個(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ǔ)任何類型的唯一值,無(wú)論是原始值或者是對(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í)例的長(zhǎng)度。

  1. set2.size//returns10 

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

  1. set2.clear(); 

我們可以使用Set對(duì)象來(lái)刪除數(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 是異步編程的一種解決方案:從語(yǔ)法上講,promise是一個(gè)對(duì)象,從它可以獲取異步操作的消息;從本意上講,它是承諾,承諾它過(guò)一段時(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è)異步操作,則此方法存在問(wèn)題。我們將有一個(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)=>{...}); 

由于篇幅過(guò)長(zhǎng),我將此系列分成上中下三篇,下篇我們?cè)谝?jiàn)。

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

2020-01-13 07:50:58

JavaScript開(kāi)發(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ù)庫(kù)

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-09-25 15:40:22

toStringvalueOf前端

2019-09-10 10:48:10

RedisJava面試題

2024-07-09 13:47:00

2024-03-04 00:25:00

機(jī)器人GPT-4

2023-11-15 07:54:03

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

2020-04-20 13:11:21

HashMap底層存儲(chǔ)

2019-08-13 08:43:07

JavaScript前端面試題

2015-08-27 09:27:34

JavaScript面試題

2024-01-01 15:30:59

JavaScriptWeb 應(yīng)用程序開(kāi)發(fā)

2020-04-29 09:30:48

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

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