javascript
中高级JavaScript易错面试题
寫(xiě)出下題的輸出
?
1、函數(shù)的實(shí)參與形參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,那么函數(shù)的length得到什么呢?
function test(a,b,c) {} test.length // 3function test(a,b,c,d) {} test.length // 4
可以看到,函數(shù)的length似乎返回了參數(shù)的個(gè)數(shù),那么對(duì)于形參和實(shí)參有沒(méi)有區(qū)別呢?答案是有。
?
function test() { console.log( arguments.length );} test(1,2,3); // 輸出 3 test(1,2,3,4); // 輸出 4可以看到,在函數(shù)中,用arguments.length取到的是函數(shù)的實(shí)際參數(shù)的個(gè)數(shù)。
另外,我們要知道var length = 10 這樣寫(xiě)是不行的,因?yàn)閘ength是JavaScript內(nèi)置的屬性,不能用作變量名或函數(shù)名。戳這里http://www.runoob.com/js/js-reserved.html查看JavaScript有哪些保留關(guān)鍵字、內(nèi)置屬性等。
所以,當(dāng)執(zhí)行fn()時(shí),this.length打印的是fn這個(gè)函數(shù)的形參的個(gè)數(shù),為0;而執(zhí)行arguments[0]()時(shí),實(shí)際上是obj.method()這個(gè)方法的arguments調(diào)用了fn函數(shù),this.length的this指向的是arguments,他的實(shí)際參數(shù)個(gè)數(shù)為2。
?
?
2、函數(shù)的解析與預(yù)解析過(guò)程(變量提升)
?
function fn(a) {console.log(a); // function a() {alert(1)}var a = 2;function a() {alert(1)}console.log(a); //2 } fn(1);?
這道題還是挺吊炸天的。。我也想了半天。。下面我來(lái)講一下,涉及到函數(shù)的解析和預(yù)解析過(guò)程。
首先遇到function fn這樣的函數(shù)聲明,會(huì)進(jìn)行函數(shù)預(yù)解析這么個(gè)過(guò)程,什么是函數(shù)預(yù)解析?通俗的說(shuō)就是,從函數(shù)體里找變量和函數(shù)聲明的過(guò)程,找到的變量(遇到var就找到了變量)不會(huì)去讀具體的值,只會(huì)賦為undefined;找到的函數(shù)聲明會(huì)賦值為整個(gè)函數(shù)體,這里有個(gè)知識(shí)點(diǎn)就是,如果找到的變量和聲明同名,那么聲明會(huì)覆蓋變量(我的理解是,畢竟函數(shù)體比undefined的強(qiáng)嘛)。
比如此例中,預(yù)解析時(shí)找到了變量a,并且賦值為undefined,找到了聲明function a(){alert(1)},為整個(gè)函數(shù)體;兩者同名,所以聲明覆蓋了變量a的值,a不再是undefined的,而是函數(shù)體。
預(yù)解析完成后調(diào)用了方法,開(kāi)始一步一步走方法。首先console.log(a),這時(shí)打印出的是函數(shù)體;接著var a = 2,a的值從函數(shù)體被改成了 2 ;接著是個(gè)function a(){}函數(shù)聲明,注意,聲明不能改變變量的值,所以走完這一句,a的值還是2,接著打印出了2。
?
?
有人肯定有這樣的疑惑,為什么a=1傳進(jìn)去沒(méi)起作用呢?這里有一個(gè)原則,就是局部變量?jī)?yōu)先,基于這個(gè)原則,我們?cè)賮?lái)分析一下a的變化過(guò)程。預(yù)解析中,a=undefined,a=function(){alert(1)},此時(shí)參數(shù)有值等于1,本應(yīng)該將a賦值為1,但卻沒(méi)有,原因是此時(shí)的a已經(jīng)等于局部函數(shù)聲明function(){alert(1)},所以外部傳進(jìn)來(lái)的參數(shù)1并沒(méi)有取代a的值;假如本例沒(méi)有function(){alert(1)}這一句,打印出的將是1, ?2。
局部變量?jī)?yōu)先原則,原理同下:
var a = 5; function fn(){var a = 10;console.log(a) // 10,局部變量?jī)?yōu)先,在局部找到a后,不會(huì)再向外查找 }?
?
3、變量提升、window的變量
if('a' in window) { var a = 10; } console.log(a); // 10首先,if(){}的花括號(hào)并不像function(){}的花括號(hào)一樣,具有自己的塊級(jí)作用域,if的花括號(hào)還是全局的環(huán)境。根據(jù)JavaScript的變量提升機(jī)制,var a會(huì)被js引擎解釋到第一行,如下:
var a; if ('a' in window) {a = 10; }接著有個(gè)知識(shí)點(diǎn),全局變量是window對(duì)象的屬性,所以'a' ?in ?window會(huì)返回true,答案就很直白了。
?
這道題我在做的時(shí)候踩了個(gè)坑,我在代碼編輯器里寫(xiě)了如下代碼:
window.onload = function(){if('a' in window){var a = 10;} console.log(a) // undefined }這時(shí)候,a這個(gè)變量是定義在匿名函數(shù)function(){}里的,屬于該函數(shù)的局部變量,所以a不再是window的對(duì)象。大家一定要注意細(xì)節(jié)。
?
?
4、基本類(lèi)型無(wú)屬性
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都是基本類(lèi)型,無(wú)法給他們添加屬性,所以a.pro和s.pro都是undefined。
undefined + 10 得到NaN(not a number)。
undefined + 'hello' 得到undefinedhello,其中undefined被轉(zhuǎn)化為字符串類(lèi)型。
?
如果實(shí)在想給字符串添加屬性,我們需要將字符串定義為對(duì)象類(lèi)型的字符串,如下:
var a= new String('objectString') a.pro = "aaaaaaa" console.log(a.pro) // aaaaaaa?
?
5、async與await的執(zhí)行
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 表示這是一個(gè)async函數(shù),await只能用在這個(gè)函數(shù)里面。
await 表示在這里等待promise返回結(jié)果了,再繼續(xù)執(zhí)行。
?
?
首先打出hello,到了await,會(huì)等待promise的返回,所以“world”不會(huì)立刻打出,接著進(jìn)入sleep函數(shù),打出666,接著開(kāi)了一個(gè)1秒的定時(shí)器,雖然js是單線(xiàn)程的,但setTimeout是異步的,在瀏覽器中,異步操作都是被加入到一個(gè)稱(chēng)為“events loop”隊(duì)列的地方,瀏覽器只會(huì)在所有同步代碼執(zhí)行完成之后采取循環(huán)讀取的方式執(zhí)行這里面的代碼,所以resolve被加入任務(wù)隊(duì)列,先打印了888,一秒后執(zhí)行了resolve,表示promise成功返回,打出了world。
?
?
以上每道題都是本渣自己的想法和理解,如有不正確的地方煩請(qǐng)讀者指正,大佬輕噴~
?
轉(zhuǎn)載于:https://www.cnblogs.com/Double-Zhang/p/7777782.html
總結(jié)
以上是生活随笔為你收集整理的中高级JavaScript易错面试题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 吉工家电脑版(下载最新版吉工家)
- 下一篇: javascript-发布订阅模式