日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

中高级JavaScript易错面试题

發布時間:2023/12/2 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中高级JavaScript易错面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫出下題的輸出

?

1、函數的實參與形參length

?

var length = 10; function fn() {console.log(this.length); } var obj = {length: 5,method: function(fn) {fn();arguments[0]();} }; console.log(obj.method(fn, 1));  // 0 2

?

?

我們都知道,[1, 2, 3].length可以得到3,"123".length可以得到3,那么函數的length得到什么呢?

function test(a,b,c) {} test.length // 3
function test(a,b,c,d) {} test.length // 4

可以看到,函數的length似乎返回了參數的個數,那么對于形參和實參有沒有區別呢?答案是有。

?

function test() { console.log( arguments.length );} test(1,2,3); // 輸出 3 test(1,2,3,4); // 輸出 4

可以看到,在函數中,用arguments.length取到的是函數的實際參數的個數。

另外,我們要知道var length = 10 這樣寫是不行的,因為length是JavaScript內置的屬性,不能用作變量名或函數名。戳這里http://www.runoob.com/js/js-reserved.html查看JavaScript有哪些保留關鍵字、內置屬性等。

所以,當執行fn()時,this.length打印的是fn這個函數的形參的個數,為0;而執行arguments[0]()時,實際上是obj.method()這個方法的arguments調用了fn函數,this.length的this指向的是arguments,他的實際參數個數為2。

?

?

2、函數的解析與預解析過程(變量提升)

?

function fn(a) {console.log(a); // function a() {alert(1)}var a = 2;function a() {alert(1)}console.log(a); //2 } fn(1);

?

這道題還是挺吊炸天的。。我也想了半天。。下面我來講一下,涉及到函數的解析和預解析過程。

首先遇到function fn這樣的函數聲明,會進行函數預解析這么個過程,什么是函數預解析?通俗的說就是,從函數體里找變量和函數聲明的過程,找到的變量(遇到var就找到了變量)不會去讀具體的值,只會賦為undefined;找到的函數聲明會賦值為整個函數體,這里有個知識點就是,如果找到的變量和聲明同名,那么聲明會覆蓋變量(我的理解是,畢竟函數體比undefined的強嘛)。

比如此例中,預解析時找到了變量a,并且賦值為undefined,找到了聲明function a(){alert(1)},為整個函數體;兩者同名,所以聲明覆蓋了變量a的值,a不再是undefined的,而是函數體。

預解析完成后調用了方法,開始一步一步走方法。首先console.log(a),這時打印出的是函數體;接著var a = 2,a的值從函數體被改成了 2 ;接著是個function a(){}函數聲明,注意,聲明不能改變變量的值,所以走完這一句,a的值還是2,接著打印出了2。

?

?

有人肯定有這樣的疑惑,為什么a=1傳進去沒起作用呢?這里有一個原則,就是局部變量優先,基于這個原則,我們再來分析一下a的變化過程。預解析中,a=undefined,a=function(){alert(1)},此時參數有值等于1,本應該將a賦值為1,但卻沒有,原因是此時的a已經等于局部函數聲明function(){alert(1)},所以外部傳進來的參數1并沒有取代a的值;假如本例沒有function(){alert(1)}這一句,打印出的將是1, ?2。

局部變量優先原則,原理同下:

var a = 5; function fn(){var a = 10;console.log(a)  // 10,局部變量優先,在局部找到a后,不會再向外查找 }

?

?

3、變量提升、window的變量

if('a' in window) { var a = 10; } console.log(a);  // 10

首先,if(){}的花括號并不像function(){}的花括號一樣,具有自己的塊級作用域,if的花括號還是全局的環境。根據JavaScript的變量提升機制,var a會被js引擎解釋到第一行,如下:

var a; if ('a' in window) {a = 10; }

接著有個知識點,全局變量是window對象的屬性,所以'a' ?in ?window會返回true,答案就很直白了。

?

這道題我在做的時候踩了個坑,我在代碼編輯器里寫了如下代碼:

window.onload = function(){if('a' in window){var a = 10;} console.log(a)  // undefined }

這時候,a這個變量是定義在匿名函數function(){}里的,屬于該函數的局部變量,所以a不再是window的對象。大家一定要注意細節。

?

?

4、基本類型無屬性

var a = 10; a.pro = 10; console.log(a.pro + a);  // NaN var s = 'hello'; s.pro = 'world'; console.log(s.pro + s)  // undefinedhello

變量a與s都是基本類型,無法給他們添加屬性,所以a.pro和s.pro都是undefined。

undefined + 10 得到NaN(not a number)。

undefined + 'hello' 得到undefinedhello,其中undefined被轉化為字符串類型。

?

如果實在想給字符串添加屬性,我們需要將字符串定義為對象類型的字符串,如下:

var a= new String('objectString') a.pro = "aaaaaaa" console.log(a.pro) // aaaaaaa

?

?

5、async與await的執行

async function sayHello() {console.log('Hello')await sleep(1000)console.log('world!') } function sleep(ms) {return new Promise(resolve => {console.log("666666");setTimeout(resolve, ms);console.log("888888")}) } sayHello()  // hello 666666 888888 world!

?

async 表示這是一個async函數,await只能用在這個函數里面。

await 表示在這里等待promise返回結果了,再繼續執行。

?

?

首先打出hello,到了await,會等待promise的返回,所以“world”不會立刻打出,接著進入sleep函數,打出666,接著開了一個1秒的定時器,雖然js是單線程的,但setTimeout是異步的,在瀏覽器中,異步操作都是被加入到一個稱為“events loop”隊列的地方,瀏覽器只會在所有同步代碼執行完成之后采取循環讀取的方式執行這里面的代碼,所以resolve被加入任務隊列,先打印了888,一秒后執行了resolve,表示promise成功返回,打出了world。

?

?

以上每道題都是本渣自己的想法和理解,如有不正確的地方煩請讀者指正,大佬輕噴~

?

轉載于:https://www.cnblogs.com/Double-Zhang/p/7777782.html

總結

以上是生活随笔為你收集整理的中高级JavaScript易错面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。