成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發(fā) 前端
undefined 和 null 有什么區(qū)別?在理解undefined和null之間的差異之前,我們先來看看它們的相似類。

[[312620]]

1.undefined 和 null 有什么區(qū)別?

在理解undefined和null之間的差異之前,我們先來看看它們的相似類。

它們屬于 JavaScript 的 7 種基本類型。

  1. letprimitiveTypes=['string','number','null','undefined','boolean','symbol','bigint']; 

它們是屬于虛值,可以使用Boolean(value)或!!value將其轉(zhuǎn)換為布爾值時,值為false。

  1. console.log(!!null);//falseconsole.log(!!undefined);//falseconsole.log(Boolean(null));//falseconsole.log(Boolean(undefined));//false 

接著來看看它們的區(qū)別。

undefined是未指定特定值的變量的默認值,或者沒有顯式返回值的函數(shù),如:console.log(1),還包括對象中不存在的屬性,這些 JS 引擎都會為其分配 undefined 值。

  1. let_thisIsUndefined;constdoNothing=()=>{};constsomeObj={a:"ay",b:"bee",c:"si"};console.log(_thisIsUndefined);//undefinedconsole.log(doNothing());//undefinedconsole.log(someObj["d"]);//undefined 

null是“不代表任何值的值”。null是已明確定義給變量的值。在此示例中,當fs.readFile方法未引發(fā)錯誤時,我們將獲得null值。

  1. fs.readFile('path/to/file',(e,data)=>{console.log(e);//當沒有錯誤發(fā)生時,打印nullif(e){console.log(e);}console.log(data);}); 

在比較null和undefined時,我們使用==時得到true,使用===時得到false:

  1. console.log(null==undefined);//trueconsole.log(null===undefined);//false 

2. && 運算符能做什么

&& 也可以叫邏輯與,在其操作數(shù)中找到第一個虛值表達式并返回它,如果沒有找到任何虛值表達式,則返回最后一個真值表達式。它采用短路來防止不必要的工作。

  1. console.log(false&&1&&[]);//falseconsole.log(""&&true&&5);//5 

使用if語句

  1. constrouter:Router=Router();router.get('/endpoint',(req:Request,res:Response)=>{letconMobile:PoolConnection;try{//dosomedboperations}catch(e){if(conMobile){conMobile.release();}}}); 

使用&&操作符

  1. constrouter:Router=Router();router.get('/endpoint',(req:Request,res:Response)=>{letconMobile:PoolConnection;try{//dosomedboperations}catch(e){conMobile&&conMobile.release()}}); 

3. || 運算符能做什么

||也叫或邏輯或,在其操作數(shù)中找到第一個真值表達式并返回它。這也使用了短路來防止不必要的工作。在支持 ES6 默認函數(shù)參數(shù)之前,它用于初始化函數(shù)中的默認參數(shù)值。

  1. console.log(null||1||undefined);//1functionlogName(name){varn=name||"Mark";console.log(n);}logName();//"Mark" 

4. 使用 + 或一元加運算符是將字符串轉(zhuǎn)換為數(shù)字的最快方法嗎?

根據(jù)MDN文檔,+是將字符串轉(zhuǎn)換為數(shù)字的最快方法,因為如果值已經(jīng)是數(shù)字,它不會執(zhí)行任何操作。

5. DOM 是什么?

DOM 代表文檔對象模型,是 HTML 和 XML 文檔的接口(API)。當瀏覽器第一次讀取(解析)HTML文檔時,它會創(chuàng)建一個大對象,一個基于 HTM L文檔的非常大的對象,這就是DOM。它是一個從 HTML 文檔中建模的樹狀結(jié)構(gòu)。DOM 用于交互和修改DOM結(jié)構(gòu)或特定元素或節(jié)點。

假設(shè)我們有這樣的 HTML 結(jié)構(gòu):

  1. <!DOCTYPEhtml><htmllanghtmllang="en"><head><metacharsetmetacharset="UTF-8"><metanamemetaname="viewport"content="width=device-width,initial-scale=1.0"><metahttp-equivmetahttp-equiv="X-UA-Compatible"content="ie=edge"><title>DocumentObjectModel</title></head><body><div><p><span></span></p><label></label><input></div></body></html> 

等價的DOM是這樣的:

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

JS 中的document對象表示DOM。它為我們提供了許多方法,我們可以使用這些方法來選擇元素來更新元素內(nèi)容,等等。

6. 什么是事件傳播?

當事件發(fā)生在DOM元素上時,該事件并不完全發(fā)生在那個元素上。在“冒泡階段”中,事件冒泡或向上傳播至父級,祖父母,祖父母或父級,直到到達window為止;而在“捕獲階段”中,事件從window開始向下觸發(fā)元素 事件或event.target。

事件傳播有三個階段:

  • 捕獲階段–事件從 window 開始,然后向下到每個元素,直到到達目標元素。
  • 目標階段–事件已達到目標元素。
  • 冒泡階段–事件從目標元素冒泡,然后上升到每個元素,直到到達 window。

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

7. 什么是事件冒泡?

當事件發(fā)生在DOM元素上時,該事件并不完全發(fā)生在那個元素上。在冒泡階段,事件冒泡,或者事件發(fā)生在它的父代,祖父母,祖父母的父代,直到到達window為止。

假設(shè)有如下的 HTML 結(jié)構(gòu):

  1. <divclassdivclass="grandparent"><divclassdivclass="parent"><divclassdivclass="child">1</div></div></div> 
對應的 JS 代碼:
  1. functionaddEvent(el,event,callback,isCapture=false){if(!el||!event||!callback||typeofcallback!=='function')return;if(typeofel==='string'){el=document.querySelector(el);};el.addEventListener(event,callback,isCapture);}addEvent(document,'DOMContentLoaded',()=>{constchild=document.querySelector('.child');constparent=document.querySelector('.parent');constgrandparent=document.querySelector('.grandparent');addEvent(child,'click',function(e){console.log('child');});addEvent(parent,'click',function(e){console.log('parent');});addEvent(grandparent,'click',function(e){console.log('grandparent');});addEvent(document,'click',function(e){console.log('document');});addEvent('html','click',function(e){console.log('html');})addEvent(window,'click',function(e){console.log('window');})}); 

addEventListener方法具有第三個可選參數(shù)useCapture,其默認值為false,事件將在冒泡階段中發(fā)生,如果為true,則事件將在捕獲階段中發(fā)生。如果單擊child元素,它將分別在控制臺上記錄child,parent,grandparent,html,document和window,這就是事件冒泡。

8. 什么是事件捕獲?

當事件發(fā)生在 DOM 元素上時,該事件并不完全發(fā)生在那個元素上。在捕獲階段,事件從window開始,一直到觸發(fā)事件的元素。

假設(shè)有如下的 HTML 結(jié)構(gòu):

  1. <divclassdivclass="grandparent"><divclassdivclass="parent"><divclassdivclass="child">1</div></div></div> 
對應的 JS 代碼:
  1. functionaddEvent(el,event,callback,isCapture=false){if(!el||!event||!callback||typeofcallback!=='function')return;if(typeofel==='string'){el=document.querySelector(el);};el.addEventListener(event,callback,isCapture);}addEvent(document,'DOMContentLoaded',()=>{constchild=document.querySelector('.child');constparent=document.querySelector('.parent');constgrandparent=document.querySelector('.grandparent');addEvent(child,'click',function(e){console.log('child');});addEvent(parent,'click',function(e){console.log('parent');});addEvent(grandparent,'click',function(e){console.log('grandparent');});addEvent(document,'click',function(e){console.log('document');});addEvent('html','click',function(e){console.log('html');})addEvent(window,'click',function(e){console.log('window');})}); 

addEventListener方法具有第三個可選參數(shù)useCapture,其默認值為false,事件將在冒泡階段中發(fā)生,如果為true,則事件將在捕獲階段中發(fā)生。如果單擊child元素,它將分別在控制臺上打印window,document,html,grandparent和parent,這就是事件捕獲。

9. event.preventDefault() 和 event.stopPropagation()方法之間有什么區(qū)別?

event.preventDefault() 方法可防止元素的默認行為。如果在表單元素中使用,它將阻止其提交。如果在錨元素中使用,它將阻止其導航。如果在上下文菜單中使用,它將阻止其顯示或顯示。event.stopPropagation()方法用于阻止捕獲和冒泡階段中當前事件的進一步傳播。

10. 如何知道是否在元素中使用了`event.preventDefault()`方法?

我們可以在事件對象中使用event.defaultPrevented屬性。它返回一個布爾值用來表明是否在特定元素中調(diào)用了event.preventDefault()。

11. 為什么此代碼 `obj.someprop.x` 會引發(fā)錯誤?

  1. constobj={};console.log(obj.someprop.x); 

顯然,由于我們嘗試訪問someprop屬性中的x屬性,而 someprop 并沒有在對象中,所以值為 undefined。記住對象本身不存在的屬性,并且其原型的默認值為undefined。因為undefined沒有屬性x,所以試圖訪問將會報錯。

12. 什么是 event.target ?

簡單來說,event.target是發(fā)生事件的元素或觸發(fā)事件的元素。

假設(shè)有如下的 HTML 結(jié)構(gòu):

  1. <divonclickdivonclick="clickFunc(event)"style="text-align:center;margin:15px;border:1pxsolidred;border-radius:3px;"><divstyledivstyle="margin:25px;border:1pxsolidroyalblue;border-radius:3px;"><divstyledivstyle="margin:25px;border:1pxsolidskyblue;border-radius:3px;"><buttonstylebuttonstyle="margin:10px">Button</button></div></div></div> 
JS 代碼如下:
  1. functionclickFunc(event){console.log(event.target);} 

如果單擊 button,即使我們將事件附加在最外面的div上,它也將打印 button 標簽,因此我們可以得出結(jié)論event.target是觸發(fā)事件的元素。

13. 什么是 event.currentTarget??

event.currentTarget是我們在其上顯式附加事件處理程序的元素。

假設(shè)有如下的 HTML 結(jié)構(gòu):

  1. <divonclickdivonclick="clickFunc(event)"style="text-align:center;margin:15px;border:1pxsolidred;border-radius:3px;"><divstyledivstyle="margin:25px;border:1pxsolidroyalblue;border-radius:3px;"><divstyledivstyle="margin:25px;border:1pxsolidskyblue;border-radius:3px;"><buttonstylebuttonstyle="margin:10px">Button</button></div></div></div> 
JS 代碼如下:
  1. functionclickFunc(event){console.log(event.currentTarget);} 

如果單擊 button,即使我們單擊該 button,它也會打印最外面的div標簽。在此示例中,我們可以得出結(jié)論,event.currentTarget是附加事件處理程序的元素。

14. == 和 === 有什么區(qū)別?

==用于一般比較,===用于嚴格比較,==在比較的時候可以轉(zhuǎn)換數(shù)據(jù)類型,===嚴格比較,只要類型不匹配就返回flase。

先來看看 == 這兄弟:

強制是將值轉(zhuǎn)換為另一種類型的過程。在這種情況下,==會執(zhí)行隱式強制。在比較兩個值之前,==需要執(zhí)行一些規(guī)則。

假設(shè)我們要比較x == y的值。

  • 如果x和y的類型相同,則 JS 會換成===操作符進行比較。
  • 如果x為null, y為undefined,則返回true。
  • 如果x為undefined且y為null,則返回true。
  • 如果x的類型是number, y的類型是string,那么返回x == toNumber(y)。
  • 如果x的類型是string, y的類型是number,那么返回toNumber(x) == y。
  • 如果x為類型是boolean,則返回toNumber(x)== y。
  • 如果y為類型是boolean,則返回x == toNumber(y)。
  • 如果x是string、symbol或number,而y是object類型,則返回x == toPrimitive(y)。
  • 如果x是object,y是string,symbol則返回toPrimitive(x) == y。
  • 剩下的 返回 false

注意:toPrimitive首先在對象中使用valueOf方法,然后使用toString方法來獲取該對象的原始值。

舉個例子。

  1. xyx == y55true1'1'truenullundefinedtrue0falsetrue'1,2'[1,2]true'[object Object]'{}true 

這些例子都返回true。

第一個示例符合條件1,因為x和y具有相同的類型和值。

第二個示例符合條件4,在比較之前將y轉(zhuǎn)換為數(shù)字。

第三個例子符合條件2。

第四個例子符合條件7,因為y是boolean類型。

第五個示例符合條件8。使用toString()方法將數(shù)組轉(zhuǎn)換為字符串,該方法返回1,2。

最后一個示例符合條件8。使用toString()方法將對象轉(zhuǎn)換為字符串,該方法返回[object Object]。

  1. xyx === y55true1'1'falsenullundefinedfalse0falsefalse'1,2'[1,2]false'[object Object]'{}false 

如果使用===運算符,則第一個示例以外的所有比較將返回false,因為它們的類型不同,而第一個示例將返回true,因為兩者的類型和值相同。

15. 為什么在 JS 中比較兩個相似的對象時返回 false?

先看下面的例子:

  1. leta={a:1};letb={a:1};letc=a;console.log(a===b);//打印false,即使它們有相同的屬性console.log(a===c);//true 

JS 以不同的方式比較對象和基本類型。在基本類型中,JS 通過值對它們進行比較,而在對象中,JS 通過引用或存儲變量的內(nèi)存中的地址對它們進行比較。這就是為什么第一個console.log語句返回false,而第二個console.log語句返回true。a和c有相同的引用地址,而a和b沒有。

16. !! 運算符能做什么?

!!運算符可以將右側(cè)的值強制轉(zhuǎn)換為布爾值,這也是將值轉(zhuǎn)換為布爾值的一種簡單方法。

  1. console.log(!!null);//falseconsole.log(!!undefined);//falseconsole.log(!!'');//falseconsole.log(!!0);//falseconsole.log(!!NaN);//falseconsole.log(!!'');//trueconsole.log(!!{});//trueconsole.log(!![]);//trueconsole.log(!!1);//trueconsole.log(!![].length);//false 

17. 如何在一行中計算多個表達式的值?

可以使用逗號運算符在一行中計算多個表達式。它從左到右求值,并返回右邊最后一個項目或最后一個操作數(shù)的值。

  1. letx=5;x=(x++,x=addFive(x),x*=2,x-=5,x+=10);functionaddFive(num){returnnum+5;} 

上面的結(jié)果最后得到x的值為27。首先,我們將x的值增加到6,然后調(diào)用函數(shù)addFive(6)并將6作為參數(shù)傳遞并將結(jié)果重新分配給x,此時x的值為11。之后,將x的當前值乘以2并將其分配給x,x的更新值為22。然后,將x的當前值減去5并將結(jié)果分配給x x更新后的值為17。最后,我們將x的值增加10,然后將更新的值分配給x,最終x的值為27。

18. 什么是提升?

提升是用來描述變量和函數(shù)移動到其(全局或函數(shù))作用域頂部的術(shù)語。

為了理解提升,需要來了解一下執(zhí)行上下文。執(zhí)行上下文是當前正在執(zhí)行的“代碼環(huán)境”。執(zhí)行上下文有兩個階段:編譯和執(zhí)行。

  • 編譯-在此階段,JS 引薦獲取所有函數(shù)聲明并將其提升到其作用域的頂部,以便我們稍后可以引用它們并獲取所有變量聲明(使用var關(guān)鍵字進行聲明),還會為它們提供默認值:undefined。
  • 執(zhí)行——在這個階段中,它將值賦給之前提升的變量,并執(zhí)行或調(diào)用函數(shù)(對象中的方法)。

注意:只有使用var聲明的變量,或者函數(shù)聲明才會被提升,相反,函數(shù)表達式或箭頭函數(shù),let和const聲明的變量,這些都不會被提升。

假設(shè)在全局使用域,有如下的代碼:

  1. console.log(y);y=1;console.log(y);console.log(greet("Mark"));functiongreet(name){return'Hello'+name+'!';}vary; 

上面分別打?。簎ndefined,1, Hello Mark!。

上面代碼在編譯階段其實是這樣的:

  1. functiongreet(name){return'Hello'+name+'!';}vary;//默認值undefined//等待“編譯”階段完成,然后開始“執(zhí)行”階段/*console.log(y);y=1;console.log(y);console.log(greet("Mark"));*/ 

編譯階段完成后,它將啟動執(zhí)行階段調(diào)用方法,并將值分配給變量。

  1. functiongreet(name){return'Hello'+name+'!';}vary;//start"execution"phaseconsole.log(y);y=1;console.log(y);console.log(greet("Mark")); 

19. 什么是作用域?

JavaScript 中的作用域是我們可以有效訪問變量或函數(shù)的區(qū)域。JS 有三種類型的作用域:全局作用域、函數(shù)作用域和塊作用域(ES6)。

  • 全局作用域——在全局命名空間中聲明的變量或函數(shù)位于全局作用域中,因此在代碼中的任何地方都可以訪問它們。
    1. //globalnamespacevarg="global";functionglobalFunc(){functioninnerFunc(){console.log(g);//canaccess"g"because"g"isaglobalvariable}innerFunc();} 
  • 函數(shù)作用域——在函數(shù)中聲明的變量、函數(shù)和參數(shù)可以在函數(shù)內(nèi)部訪問,但不能在函數(shù)外部訪問。
    1. functionmyFavoriteFunc(a){if(true){varb="Hello"+a;}returnb;}myFavoriteFunc("World");console.log(a);//ThrowsaReferenceError"a"isnotdefinedconsole.log(b);//doesnotcontinuehere 
  • 塊作用域-在塊{}中聲明的變量(let,const)只能在其中訪問。
    1. functiontestBlock(){if(true){letz=5;}returnz;}testBlock();//ThrowsaReferenceError"z"isnotdefined 
  • 作用域也是一組用于查找變量的規(guī)則。如果變量在當前作用域中不存在,它將向外部作用域中查找并搜索,如果該變量不存在,它將再次查找直到到達全局作用域,如果找到,則可以使用它,否則引發(fā)錯誤,這種查找過程也稱為作用域鏈。
    1. /*作用域鏈內(nèi)部作用域->外部作用域->全局作用域*///全局作用域varvariable1="Comrades";varvariable2="Sayonara";functionouter(){//外部作用域varvariable1="World";functioninner(){//內(nèi)部作用域varvariable2="Hello";console.log(variable2+""+variable1);}inner();}outer();//HelloWorld 

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

20. 什么是閉包?

這可能是所有問題中最難的一個問題,因為閉包是一個有爭議的話題,這里從個人角度來談談,如果不妥,多多海涵。

閉包就是一個函數(shù)在聲明時能夠記住當前作用域、父函數(shù)作用域、及父函數(shù)作用域上的變量和參數(shù)的引用,直至通過作用域鏈上全局作用域,基本上閉包是在聲明函數(shù)時創(chuàng)建的作用域。

看看小例子:

  1. //全局作用域varglobalVar="abc";functiona(){console.log(globalVar);}a();//"abc" 

在此示例中,當我們聲明a函數(shù)時,全局作用域是a閉包的一部分。

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

變量globalVar在圖中沒有值的原因是該變量的值可以根據(jù)調(diào)用函數(shù)a的位置和時間而改變。但是在上面的示例中,globalVar變量的值為abc。

來看一個更復雜的例子:

  1. varglobalVar="global";varouterVar="outer"functionouterFunc(outerParam){functioninnerFunc(innerParam){console.log(globalVar,outerParam,innerParam);}returninnerFunc;}constx=outerFunc(outerVar);outerVar="outer-2";globalVar="guess"x("inner"); 

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

上面打印結(jié)果是 guess outer inner。

當我們調(diào)用outerFunc函數(shù)并將返回值innerFunc函數(shù)分配給變量x時,即使我們?yōu)閛uterVar變量分配了新值outer-2,outerParam也繼續(xù)保留outer值,因為重新分配是在調(diào)用outerFunc之后發(fā)生的,并且當我們調(diào)用outerFunc函數(shù)時,它會在作用域鏈中查找outerVar的值,此時的outerVar的值將為 "outer"。

現(xiàn)在,當我們調(diào)用引用了innerFunc的x變量時,innerParam將具有一個inner值,因為這是我們在調(diào)用中傳遞的值,而globalVar變量值為guess,因為在調(diào)用x變量之前,我們將一個新值分配給globalVar。

下面這個示例演示沒有理解好閉包所犯的錯誤:

  1. constarrFuncs=[];for(vari=0;i<5;i++){arrFuncs.push(function(){returni;});}console.log(i);//iis5for(leti=0;i<arrFuncs.length;i++){console.log(arrFuncs[i]());//都打印5} 

由于閉包,此代碼無法正常運行。var關(guān)鍵字創(chuàng)建一個全局變量,當我們 push 一個函數(shù)時,這里返回的全局變量i。因此,當我們在循環(huán)后在該數(shù)組中調(diào)用其中一個函數(shù)時,它會打印5,因為我們得到i的當前值為5,我們可以訪問它,因為它是全局變量。

因為閉包在創(chuàng)建變量時會保留該變量的引用而不是其值。我們可以使用IIFES或使用 let 來代替 var 的聲明。

21. JavaScript 中的虛值是什么?

  1. constfalsyValues=['',0,null,undefined,NaN,false]; 

簡單的來說虛值就是是在轉(zhuǎn)換為布爾值時變?yōu)?false 的值。

22. 如何檢查值是否虛值?

使用 Boolean 函數(shù)或者 !! 運算符。

23. 'use strict' 是干嘛用的?

"use strict" 是 ES5 特性,它使我們的代碼在函數(shù)或整個腳本中處于嚴格模式。嚴格模式幫助我們在代碼的早期避免 bug,并為其添加限制。

嚴格模式的一些限制:

  • 變量必須聲明后再使用
  • 函數(shù)的參數(shù)不能有同名屬性,否則報錯
  • 不能使用with語句
  • 不能對只讀屬性賦值,否則報錯
  • 不能使用前綴 0 表示八進制數(shù),否則報錯
  • 不能刪除不可刪除的屬性,否則報錯
  • 不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
  • eval不能在它的外層作用域引入變量
  • eval和arguments不能被重新賦值
  • arguments不會自動反映函數(shù)參數(shù)的變化
  • 不能使用arguments.callee
  • 不能使用arguments.caller
  • 禁止this指向全局對象
  • 不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
  • 增加了保留字(比如protected、static和interface)

設(shè)立”嚴格模式”的目的,主要有以下幾個:

  • 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全;
  • 提高編譯器效率,增加運行速度;
  • 為未來新版本的Javascript做好鋪墊。

24. JavaScript 中 `this` 值是什么?

基本上,this指的是當前正在執(zhí)行或調(diào)用該函數(shù)的對象的值。this值的變化取決于我們使用它的上下文和我們在哪里使用它。

  1. constcarDetails={name:"FordMustang",yearBought:2005,getName(){returnthis.name;},isRegistered:true};console.log(carDetails.getName());//FordMustang 

這通常是我們期望結(jié)果的,因為在getName方法中我們返回this.name,在此上下文中,this指向的是carDetails對象,該對象當前是執(zhí)行函數(shù)的“所有者”對象。

接下我們做些奇怪的事情:

  1. varname="FordRanger";vargetCarName=carDetails.getName;console.log(getCarName());//FordRanger 

上面打印Ford Ranger,這很奇怪,因為在第一個console.log語句中打印的是Ford Mustang。這樣做的原因是getCarName方法有一個不同的“所有者”對象,即window對象。在全局作用域中使用var關(guān)鍵字聲明變量會在window對象中附加與變量名稱相同的屬性。請記住,當沒有使用“use strict”時,在全局作用域中this指的是window對象。

  1. console.log(getCarName===window.getCarName);//trueconsole.log(getCarName===this.getCarName);//true 

本例中的this和window引用同一個對象。

解決這個問題的一種方法是在函數(shù)中使用apply和call方法。

  1. console.log(getCarName.apply(carDetails));//FordMustangconsole.log(getCarName.call(carDetails));//FordMustang 

apply和call方法期望第一個參數(shù)是一個對象,該對象是函數(shù)內(nèi)部this的值。

IIFE或立即執(zhí)行的函數(shù)表達式,在全局作用域內(nèi)聲明的函數(shù),對象內(nèi)部方法中的匿名函數(shù)和內(nèi)部函數(shù)的this具有默認值,該值指向window對象。

  1. (function(){console.log(this);})();//打印"window"對象functioniHateThis(){console.log(this);}iHateThis();//打印"window"對象constmyFavoriteObj={guessThis(){functiongetName(){console.log(this.name);}getName();},name:'MarkoPolo',thisIsAnnoying(callback){callback();}};myFavoriteObj.guessThis();//打印"window"對象myFavoriteObj.thisIsAnnoying(function(){console.log(this);//打印"window"對象}); 

如果我們要獲取myFavoriteObj對象中的name屬性(即Marko Polo)的值,則有兩種方法可以解決此問題。

一種是將 this 值保存在變量中。

  1. constmyFavoriteObj={guessThis(){constself=this;//把this值保存在self變量中functiongetName(){console.log(self.name);}getName();},name:'MarkoPolo',thisIsAnnoying(callback){callback();}}; 

第二種方式是使用箭頭函數(shù)

  1. constmyFavoriteObj={guessThis(){constgetName=()=>{console.log(this.name);}getName();},name:'MarkoPolo',thisIsAnnoying(callback){callback();}}; 

箭頭函數(shù)沒有自己的 this。它復制了這個封閉的詞法作用域中this值,在這個例子中,this值在getName內(nèi)部函數(shù)之外,也就是myFavoriteObj對象。

25. 對象的 prototype(原型) 是什么?

簡單地說,原型就是對象的藍圖。如果它存在當前對象中,則將其用作屬性和方法的回退。它是在對象之間共享屬性和功能的方法,這也是JavaScript實現(xiàn)繼承的核心。

  1. consto={};console.log(o.toString());//logs[objectObject] 

即使o對象中不存在o.toString方法,它也不會引發(fā)錯誤,而是返回字符串[object Object]。當對象中不存在屬性時,它將查看其原型,如果仍然不存在,則將其查找到原型的原型,依此類推,直到在原型鏈中找到具有相同屬性的屬性為止。原型鏈的末尾是Object.prototype。

  1. console.log(o.toString===Object.prototype.toString);//logstrue 

 

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

2020-01-18 07:55:28

JavaScript開發(fā)

2023-04-10 14:57:57

AI復活逝者

2021-02-26 05:20:42

Java參數(shù)化泛型

2019-07-18 15:42:53

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

2024-03-07 07:37:03

AQS線程獨占鎖

2022-03-31 09:50:45

JS面試題

2019-12-26 09:52:33

Redis集群線程

2024-06-04 14:52:28

2013-01-05 14:51:34

JavaScriptjQuery面試

2024-07-09 13:47:00

2024-03-04 00:25:00

機器人GPT-4

2023-09-04 08:28:34

JavaScripforEach 循環(huán)

2023-11-15 07:54:03

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

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ù)庫

2020-04-20 13:11:21

HashMap底層存儲

2022-05-04 23:09:33

TS交叉運算工具

2020-04-29 09:30:48

Google面試題工程師
點贊
收藏

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

主站蜘蛛池模板: 亚洲一级毛片 | 在线播放一区二区三区 | 国产精品日韩欧美一区二区三区 | 超碰在线国产 | 成人在线小视频 | 欧美一区精品 | 国产亚洲一区二区三区在线 | 日韩精品激情 | 伊人成人免费视频 | 国产日韩欧美一区 | 91久久久久久久久 | 人人插人人 | 成人免费淫片aa视频免费 | 精品欧美乱码久久久久久1区2区 | 亚洲a在线观看 | 精品九九九 | 四季久久免费一区二区三区四区 | 国产一区二区三区免费 | a级毛片毛片免费观看久潮喷 | 久久新 | 91精品国产色综合久久 | 亚洲国产精品成人无久久精品 | av毛片| 青娱乐av| 日韩毛片中文字幕 | 国产精品久久九九 | 91精品久久久久久久久 | 国产夜恋视频在线观看 | 欧美电影一区 | 黄色在线免费看 | 国产一区二区三区久久久久久久久 | 一区二区中文 | 日韩一区二区三区在线视频 | 香蕉一区 | 操一草| 四虎成人免费视频 | 天堂久久久久久久 | 中文字幕高清视频 | 亚洲午夜精品视频 | 久久精品中文字幕 | 国产精品一区二区三区免费观看 |