javascript
原生JS面试题
1. 什么是事件委托?為什么這樣做?
答:它還有一個名字叫事件代理,事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。
為什么這樣做呢?通過事件委托可以減少事件處理程序數(shù)量,這樣就能大大的減少與dom的交互次數(shù),提高性能;
2. js數(shù)據(jù)類型?
答:JS的數(shù)據(jù)類型有8種。
在ES5的時候,我們認(rèn)知的數(shù)據(jù)類型確實是 6種:Number、String、Boolean、undefined、object、Null。
ES6 中新增了一種 Symbol?。這種類型的對象永不相等,即始創(chuàng)建的時候傳入相同的值,可以解決屬性名沖突的問題,做為標(biāo)記。
谷歌67版本中還出現(xiàn)了一種 bigInt。是指安全存儲、操作大整數(shù)。(但是很多人不把這個做為一個類型)。
JS數(shù)據(jù)類型:Object 中包含了哪幾種類型?其中包含了Date、function、Array等(這三種比較常用)。
3. for in、Object.keys()區(qū)別?哪個要用于遍歷原型鏈上的屬性?
答:for-in 是javaScript中最常見的迭代語句,常常用來枚舉對象的屬性。某些情況下,可能按照隨機順序遍歷數(shù)組元素;而Object.keys(),可以返回以對象的屬性為元素的數(shù)組。數(shù)組中屬性名的順序跟使用???????for-in遍歷返回的順序是一樣的。
二者遍歷的數(shù)量是不同的,for-in 不單可以枚舉自身屬性,也可以枚舉繼承自原型鏈上的屬性,Object.keys()只可以枚舉自身屬性。
for-in會遍歷原型鏈上的屬性,而Object.keys不會。
4.NaN == NaN 的結(jié)果是什么?為什么?
答:NaN == NaN ?的執(zhí)行結(jié)果是 false。因為JavaScript規(guī)定,NaN表示的是非數(shù)字,但是這個非數(shù)字也是不同的,因此 NaN 不等于 NaN,兩個NaN永遠(yuǎn)不可能相等。 ?
5.說一下你對Promise的了解?說說你對Promise的原理的理解?
答:Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大。
所謂promise,簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。
6.?Promise.all(),一個失敗后,其他的還返回嗎?
答:不會返回,promise.all()失敗的時候只返回最先被reject失敗狀態(tài)的那個實例對象的值
7.Promise.all()、Promise.race()區(qū)別?‘
答:兩者都是可以同時調(diào)用多個promise實現(xiàn),Promise.all可以將多個實例組裝成一個新的實例,成功的時候返回一個成功數(shù)組,失敗的時候則返回最先被reject失敗狀態(tài)的值;其中有一個實例不成功則返回reject;race()是賽跑的意思,也就是說Promise.race([p1, p2, p3])里面的結(jié)果哪個獲取的快,就返回哪個結(jié)果,不管結(jié)果本身是成功還是失敗
8.Promise有哪些狀態(tài)。
答:有三個狀態(tài):pending : 等待 ????fullfilled(resolved) :成功 ????reject: 失敗
9.簡單說一下async/await的了解?(****)(請參考https://www.jianshu.com/p/fd6933ff6b81)
答:async/await是寫異步代碼的新方式,它是generator的語法糖,以前的方法有回調(diào)函數(shù)和 Promise。async/await是基于Promise實現(xiàn)的,它不能用于普通的回調(diào)函數(shù)。async/await與Promise一樣,是非阻塞的。async/await使得異步代碼看起來像同步代碼,這正是它的魔力所在。單一的 Promise 鏈并不能發(fā)現(xiàn) async/await 的優(yōu)勢,但是,如果需要處理由多個 Promise 組成的 then 鏈的時候,優(yōu)勢就能體現(xiàn)出來了
10. Async&await和promise有什么區(qū)別?(參考https://www.jianshu.com/p/51f5fd21588e)
答:(1)函數(shù)前面多了一個async關(guān)鍵字。await關(guān)鍵字只能用在async定義的函數(shù)內(nèi)。async函數(shù)會引式返回一個promise
(2)簡潔:使用async和await明顯節(jié)約了不少代碼,不需要.then,不需要寫匿名函數(shù)處理promise的resolve的值,不需要定義多余的data變量,還避免了嵌套代碼。
(3)async/await讓try/catch 可以同時處理同步和異步錯誤。try/catch不能處理JSON.parse的錯誤,因為他在promise中。此時需要.catch,這樣的錯誤處理代碼非常冗余。并且,在我們的實際生產(chǎn)代碼會更加復(fù)雜
(4)async/await能夠使得代碼調(diào)試更簡單
11.有10個任務(wù),使用promise如何同時運行5個任務(wù)
答:可以利用Promise.all()方法來同時支行5個任務(wù)
12.簡單介紹原型鏈?
答:所有對象都有自己的原型對象(prototype)。一方面,任何一個對象,都可以充當(dāng)其他對象的原型;另一方面,由于原型對象也是對象,所以它也有自己的原型。因此,就會形成一個“原型鏈”(prototype?chain)最終都可以上溯到Object.prototype Object.prototype對象有沒有它的原型呢?回答Object.prototype的原型是null。null沒有任何屬性和方法,也沒有自己的原型。因此,原型鏈的盡頭就是null。
13.如果后端有3個請求,如何保證順序
答:可以使用Promise鏈?zhǔn)秸{(diào)用,按順序執(zhí)行;也可以使用async函數(shù)和關(guān)鍵字await順序執(zhí)行
14.如果Promise沒有all方法的話,你怎么實現(xiàn)all。
?
15.await后面可以是一個普通的函數(shù)嗎?
答:可以,但是其結(jié)果會轉(zhuǎn)化為promise的resolve狀態(tài)
16.es6的set、map介紹?
答:set和map都是es6新增的數(shù)據(jù)結(jié)構(gòu)。其中set是一個類數(shù)組結(jié)構(gòu),值是唯一的,沒有重復(fù)的值。map類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當(dāng)作鍵。也就是說,Object 結(jié)構(gòu)提供了“字符串—值”的對應(yīng),Map 結(jié)構(gòu)提供了“值—值”的對應(yīng),是一種更完善的 Hash 結(jié)構(gòu)實現(xiàn)。如果你需要“鍵值對”的數(shù)據(jù)結(jié)構(gòu),Map 比 Object 更合適。
17.數(shù)組去重除了set外,還可以怎么做?
答:
filter()和indexOf()實現(xiàn)去重
reduce()和includes()實現(xiàn)去重
雙重for循環(huán) + splice() 或 雙重for循環(huán) + ?push() ?????(ES5的方法)
18.簡述一下對閉包理解?
答:閉包:在一個外函數(shù)中定義了一個內(nèi)函數(shù),內(nèi)函數(shù)里運用了外函數(shù)的臨時變量,并且外函數(shù)的返回值是內(nèi)函數(shù)的引用。這樣就構(gòu)成了一個閉包。一般情況下,在我們認(rèn)知當(dāng)中,如果一個函數(shù)結(jié)束,函數(shù)的內(nèi)部所有東西都會釋放掉,還給內(nèi)存,局部變量都會消失。但是閉包是一種特殊情況,如果外函數(shù)在結(jié)束的時候發(fā)現(xiàn)有自己的臨時變量將來會在內(nèi)部函數(shù)中用到,就把這個臨時變量綁定給了內(nèi)部函數(shù),然后自己再結(jié)束。經(jīng)常用閉包來實現(xiàn)面向?qū)ο缶幊?/span>
一個函數(shù)和它的周圍狀態(tài)的引用捆綁在一起的組合
是一個可以讀取其他函數(shù)內(nèi)部變量的函數(shù),在js中只有函數(shù)內(nèi)部的函數(shù)才可以讀取該函數(shù)內(nèi)部的變量,因此,閉包可以是一個函數(shù)中返回的函數(shù)。
閉包的好處:可以讀取其他函數(shù)你內(nèi)部的變量,并將其一直保存在內(nèi)存中。
壞處:?可能會造成內(nèi)存泄露或者內(nèi)存溢出
19.es6相關(guān)的知識知道哪些?
答:有很多,如Promise async函數(shù) 箭頭函數(shù) Symbol新的基本數(shù)據(jù)類型,class類等等
20.對箭頭函數(shù)的了解,箭頭函數(shù)的優(yōu)缺點?
答:箭頭函數(shù)是匿名函數(shù),ES5匿名函數(shù)的語法糖,并且沒有自己的this,arguments,super或 new.target。
它的優(yōu)點是:
(1)簡潔的語法、???
(2)隱士返回,如 下面的代碼可以去掉return,代碼移到一行,減少代碼量numbers.map((number)=>number*2)
(3)解決了this的指向問題,原生的寫法this指向的是調(diào)用者,箭頭函數(shù)this綁定的是定義時的那個對象。如果有對象嵌套的情況,則this綁定到最近的一層對象上
它的缺點是:
(1)做為構(gòu)造函數(shù)的時候不能使用箭頭函數(shù)
(2)真正需要this的時候如給元素綁定click事件的 時候,執(zhí)行的回調(diào)函數(shù)不能使用箭頭函數(shù)。
(3)我們需要使用arguments對象的時候不能使箭頭函數(shù)。箭頭函數(shù)中沒有arguments對象。
21.箭頭函數(shù)與普通函數(shù)的區(qū)別?
答:
(1)定義的形式不同。
(2)箭頭函數(shù)全都是匿名函數(shù)。
(3)普通函數(shù)的this指向調(diào)用者,箭頭函數(shù)的 this 永遠(yuǎn)指向其上下文的 this,任何方法都改變不了箭頭函數(shù)this指向,如 call() , bind() , apply()
(4)箭頭函數(shù)不具有prototype屬性,新建的對象的隱式原型無法被指定為箭頭函數(shù)的原型
(5)箭頭函數(shù)不能用于構(gòu)造函數(shù)
(6)箭頭函數(shù)不能Generator函數(shù)
(7)箭頭函數(shù)不具有arguments對象
22.const、let、var的區(qū)別??
答:var 聲明的變量屬于函數(shù)作用域,let 和 const 聲明的變量屬于塊級作用域;
var 存在變量提升現(xiàn)象,而 let 和 const 沒有此類現(xiàn)象;
var 變量可以重復(fù)聲明,而在同一個塊級作用域,let 變量不能重新聲明,const 變量不能修改
Var 不存在暫時性死區(qū),而let const存在暫時性死區(qū)
23.get、post區(qū)別?
答:?Get 方法通過 URL 請求來傳遞用戶的數(shù)據(jù),將表單內(nèi)各字段名稱與其內(nèi)容,以成對的字符串連接,置于 action 屬性所指程序的 url 后,數(shù)據(jù)都會直接顯示在 url 上,就像用戶點擊一個鏈接一樣;Post 方法通過 HTTP post 機制,將表單內(nèi)各字段名稱與其內(nèi)容放置在 HTML 表頭(header)內(nèi)一起傳送給服務(wù)器端交由 action 屬性能所指的程序處理,該程序會通過標(biāo)準(zhǔn)輸入(stdin)方式,將表單的數(shù)據(jù)讀出并加以處理;
Get 方式需要使用 Request,QueryString 來取得變量的值;而 Post 方式通過RequestForm 來訪問提交的內(nèi)容;
Get 方式傳輸?shù)臄?shù)據(jù)量非常小,一般限制在 2 KB 左右,但是執(zhí)行效率卻比 Post 方法好;而 Post 方式傳遞的數(shù)據(jù)量相對較大,它是等待服務(wù)器來讀取數(shù)據(jù),不過也有字節(jié)限制,這是為了避免對服務(wù)器用大量數(shù)據(jù)進(jìn)行惡意攻擊。建議:除非你肯定你提交的數(shù)據(jù)可以一次性提交,否則請盡量用 Post 方法;
Get 方式提交數(shù)據(jù),會帶來安全問題,比如一個登陸頁面,通過 Get 方式提交數(shù)據(jù)時,用戶名和密碼將出現(xiàn)在 URL 上,如果頁面可以被緩存或者其他人可以訪問客戶這臺機器,就可以從歷史記錄獲得該用戶的帳號和密碼,所以表單提交建議使用 Post 方法;
get是從服務(wù)器上獲取數(shù)據(jù),post是向服務(wù)器傳送數(shù)據(jù)。
get方式的安全性較Post方式要差些,包含機密信息的話,建議用Post數(shù)據(jù)提交方式;
在做數(shù)據(jù)查詢時,建議用Get方式;而在做數(shù)據(jù)添加、修改或刪除時,建議用Post方式。
24.axios的原理,基于什么實現(xiàn)的。
答:Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
axios還是屬于 XMLHttpRequest, 因此需要實現(xiàn)一個ajax;還需要一個promise對象來對結(jié)果進(jìn)行處理。
25.Axios二次分裝的目的?
答:二次封裝axios,方便我們后續(xù)項目的使用。
api統(tǒng)一管理,不管接口有多少,所有的接口都可以非常清晰,容易維護(hù).通常我們的項目會越做越大,頁面也會越來越多,如果頁面非常的少,直接用axios也沒有什么大的影響,那頁面組件多了起來,上百個接口呢,這個時候后端改了接口,多加了一個參數(shù)什么的呢?那就只有找到那個頁面,進(jìn)去修改.整個過程很繁瑣不易于項目的維護(hù)和迭代.
26.說說constructor()?
答:?constructor的作用是可以知道實例對象的構(gòu)造函數(shù)是誰,constructor屬性表示原型對象與構(gòu)造函數(shù)之間的關(guān)聯(lián)關(guān)系,如果修改了原型對象,一般會同時修改constructor屬性,防止引用的時候出錯。
27.class與function定義類的區(qū)別?
答:
(5)class定義的類沒有私有方法和私有屬性
28.Session Storage一刷新還有嗎?
答:?刷新頁面session stroage是不會消失的,只有關(guān)閉瀏覽器才會消失,如果出現(xiàn)了頁面刷新導(dǎo)致session storag消失的問題,請排查頁面刷新時是否執(zhí)行了sessionStroage.clear()操作。
29.1+2等于3嗎,在程序里面?
答:?等于,但是0.1+0.2 = 0.30000000000000004。原因是由于JS浮點數(shù)存儲機制:
解決方法:自己實現(xiàn)浮點數(shù)加法,先轉(zhuǎn)化可以計算的整數(shù),再相加,最后轉(zhuǎn)化為小數(shù),精度取一定位數(shù)如5
30.發(fā)布訂閱怎么實現(xiàn)的?
答:發(fā)布---訂閱模式又叫觀察者模式,它定義了對象間的一種一對多的關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象,當(dāng)一個對象發(fā)生改變時,所有依賴于它的對象都將得到通知。
訂閱者(Subscriber)把自己想訂閱的事件注冊(Subscribe)到調(diào)度中心(Event Channel),當(dāng)發(fā)布者(Publisher)發(fā)布該事件(Publish Event)到調(diào)度中心,也就是該事件觸發(fā)時,由調(diào)度中心統(tǒng)一調(diào)度(Fire Event)訂閱者注冊到調(diào)度中心的處理代碼。
31.自己實現(xiàn)發(fā)布訂閱者模式 如何實現(xiàn)?
答:
1. 創(chuàng)建一個對象
2. 在該對象上創(chuàng)建一個緩存列表(調(diào)度中心)
3. on 方法用來把函數(shù) fn 都加到緩存列表中(訂閱者注冊事件到調(diào)度中心)
4. emit 方法取到 arguments 里第一個當(dāng)做 event,根據(jù) event 值去執(zhí)行對應(yīng)緩存列表中的函數(shù)(發(fā)布者發(fā)布事件到調(diào)度中心,調(diào)度中心處理代碼)
5. off 方法可以根據(jù) event 值取消訂閱(取消訂閱)
6. once 方法只監(jiān)聽一次,調(diào)用完畢后刪除緩存函數(shù)(訂閱一次)
32.如何移除訂閱發(fā)布者模式
答:實現(xiàn)一個off方法根據(jù)event值取消訂閱,從訂閱列表中移除即可。
33.如果用本機存儲的方式實現(xiàn)定時任務(wù)過期?
答:本題的核心是考查的是如何實現(xiàn)localstorage本地定時緩存?方案:ES5擴展Storage,思路很簡單,存儲的值加一個時間戳,下次取值時驗證時間戳;注意:?localStorage只能存儲字符,存入時將對象轉(zhuǎn)為json字符串,讀取時也要解析
34.暫時性死區(qū)的報錯是什么樣的,為什么會有暫時性死區(qū),Var為什么沒有暫時性死區(qū)?
答:
if(true){console.log(tmp); let tmp = 90;}如上代碼會出現(xiàn)暫時性死區(qū)報錯,報措信息“Uncaught ReferenceError: Cannot access 'tmp' before initialization at <anonymous>:3:7”
出現(xiàn)暫時性死區(qū)的原因:let/const 命令會使區(qū)塊形成封閉的作用域。若在聲明之前使用變量,就會報錯。總之,在代碼塊內(nèi),使用 let 命令聲明變量之前,該變量都是不可用的。這在語法上,稱為 “暫時性死區(qū)”( temporal dead zone,簡稱 TDZ)。
Var 具有聲明提升的特性,所以在使用前調(diào)用該變量值為undefined,并不會出現(xiàn)暫時性死區(qū)現(xiàn)象
35.數(shù)組里面常用的方法
答:
1. push ??向數(shù)組的末尾添加一項或多項元素
2. pop ????刪除數(shù)組的最后一項
3. shift ???刪除數(shù)組的首項
4. unshift ?向數(shù)組的開頭添加一或多項
5. splice ?增刪改
6. slice ???截取數(shù)組(復(fù)制數(shù)組)
7. join ?????用指定的分隔符將數(shù)組每一項拼接為字符串
8. concat ?用于連接兩個或多個數(shù)組
9. sort ??對數(shù)組的元素進(jìn)行排序
10. reverse ?倒序數(shù)組
36.forEach和map循環(huán)區(qū)別
答:最大的區(qū)別是forEach沒有返回值,map有返回值,可以return;
37.影響js性能的操作
答:
38.談?wù)剬ι顪\拷貝的理解,怎么實現(xiàn)深淺拷貝的?
答:淺拷貝只復(fù)制指向某個對象的指針,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存。但深拷貝會另外創(chuàng)造一個一模一樣的對象,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象。
淺拷貝的實現(xiàn)方式:
(1)Object.assign()
深拷貝的實現(xiàn)方式:
(2)手寫遞歸方法:遞歸方法實現(xiàn)深度克隆原理:遍歷對象、數(shù)組直到里邊都是基本數(shù)據(jù)類型,然后再去復(fù)制,就是深度拷貝(源碼可參考:https://www.cnblogs.com/secretAngel/p/10188716.html)
39.類數(shù)組有用過嗎,什么情況下用,怎么轉(zhuǎn)化成真正數(shù)組
?答:有用過,比如document.getElementsByTagName()的返回值就是一個類數(shù)組,比如函數(shù)中的arguments對象也是一個類數(shù)組。 ?
常用的類數(shù)組轉(zhuǎn)數(shù)組的方法有3種:
40.談?wù)則his指向。
答:this是函數(shù)運行時自動生成的一個內(nèi)部對象,只能在函數(shù)內(nèi)部使用,但總指向調(diào)用它的對象。它的指向由調(diào)用它的對象來決定,如:
?????1.在全局中this指向window ?
?????2.直接調(diào)用函數(shù)this指向window
?????3.事件處理函數(shù)中this指向綁定事件的元素
?????4.obj.fn(); ?fn函數(shù)中this指向obj
?????5.回調(diào)函數(shù)中this指向window
?????6.構(gòu)造函數(shù)中this指向?qū)嵗瘜ο????
41.js里哪些操作會造成內(nèi)存泄漏
答:(1)在函數(shù)中定義全局變量(2)閉包。閉包可以維持函數(shù)內(nèi)局部變量,使其得不到釋放。(3)刪除元素卻沒有清除DOM元素引用(4)被遺忘的定時器或者回調(diào)(5)子元素存在引用引起的內(nèi)存泄漏
42.js里什么是垃圾回收機制
答:找出不再使用的變量,然后釋放掉其占用的內(nèi)存,但是這個過程不是實時的,因為其開銷比較大,所以垃圾回收系統(tǒng)(GC)會按照固定的時間間隔,周期性的執(zhí)行。
兩種方法:1.標(biāo)記清除 ??2.引用計數(shù)
43.js延遲加載都有哪些方式
答:JS延遲加載,也就是等頁面加載完成之后再加載 JavaScript 文件。
44.js緩存的三種方法及區(qū)別與特點
答:H5本地存儲:sessionStorage:臨時的會話存儲,只要當(dāng)前的會話窗口未關(guān)閉,存儲的信息就不會丟失,即便刷新了頁面或者在編輯器中更改了代碼,存儲的會話信息也不會丟失。localStorage是一種永久存儲,會一直將數(shù)據(jù)存儲在客戶端的儲存方式,即使關(guān)閉了瀏覽器,下次打開的時候仍然可以看到之前存儲的未主動清除的數(shù)據(jù)(即便是殺毒軟件或者瀏覽器自帶的清除功能,也不能將localStorage存儲的數(shù)據(jù)清除掉)
Cookie:Cookie是存儲在用戶計算機上的小文件,保存特定客戶端和網(wǎng)站的適量數(shù)據(jù),并可以由Web服務(wù)器或客戶端瀏覽器訪問,允許服務(wù)器提供針對特定用戶定制的頁面,或者頁面本身可以包含一些知道cookie中的數(shù)據(jù)的腳本。
cookie和H5本地存儲的區(qū)別
1.cookie兼容所有的瀏覽器(本地cookie谷歌不支持),storage不支持IE6~8;
2.二者對存儲的內(nèi)容均有大小限制,前者同源情況寫一般不能存儲4kb的內(nèi)容,后者同源一般能存儲只能存儲5MB的數(shù)據(jù)
3.cookie有過期時間,localStorage是永久存儲(如果你不手動去刪除的話)
4.一些瀏覽器處于安全的角度可能會禁用cookie,但無法禁用localStorage
45.cookie有什么弊端
答:cookie兼容所有的瀏覽器,但其存儲的數(shù)據(jù)是有大小限制的,一般同源是4kb;cookie本地存儲的數(shù)據(jù)會被發(fā)送到服務(wù)器(所以建議在服務(wù)器環(huán)境下使用cookie);存在跨域訪問問題;浪費帶寬等等;
46.怎么阻止冒泡和瀏覽器默認(rèn)事件
答:標(biāo)準(zhǔn)瀏覽器: ?阻止冒泡e.stopPropagation() 阻止默認(rèn)事件e.preventDefault()
????ie瀏覽器: ?阻止冒泡e.cancleBubble=true?阻止默認(rèn)事件e.returnValue = fasle;
47.什么是面向?qū)ο缶幊?#xff0c;三個屬性是什么
答:面向?qū)ο缶幊淌且环N編程開發(fā)思想。?它將真實世界各種復(fù)雜的關(guān)系,抽象為一個個對象,然后由對象之間的分工與合作,完成對真實世界的模擬。,每一個對象都是功能中心,具有明確分工,可以完成接受信息、處理數(shù)據(jù)、發(fā)出信息等任務(wù)。?因此,面向?qū)ο缶幊叹哂徐`活、代碼可復(fù)用、高度模塊化等特點,容易維護(hù)和開發(fā),比起由一系列函數(shù)或指令組成的傳統(tǒng)的過程式編程(procedural programming),更適合多人合作的大型軟件項目。
三個屬性:封裝、繼承、多態(tài)
48.前端調(diào)試bug都有哪些方法
答:
49.Js里面的事件循環(huán)
答:答案參考https://www.jianshu.com/p/184988903562來學(xué)習(xí)
50.怎么實現(xiàn)圖片懶加載(答案參考:https://www.jianshu.com/p/6d3e38728c10)
答:定義:當(dāng)打開一個有很多圖片的頁面時,先只加載頁面上看到的圖片,等滾動到頁面下面時,再加載所需的圖片。這就是圖片懶加載。
作用:減少或延遲請求數(shù),緩解瀏覽器的壓力,增強用戶體驗
實現(xiàn)方式:
設(shè)置圖片src屬性為同一張圖片,同時自定義一個data-src屬性來存儲圖片的真實地址
頁面初始化顯示的時候或者瀏覽器發(fā)生滾動的時候判斷圖片是否在視野中
當(dāng)圖片在視野中時,通過js自動改變該區(qū)域的圖片的src屬性為真實地址
51.數(shù)組里面的排序有哪些方法,怎么用
插入排序:
52.多維數(shù)組怎么拍平,扁平,怎么去實現(xiàn)這個方法呢!
答:方法1:ES6的方法數(shù)組.flat();
方法2:ES5的方法
53.數(shù)組元素的求和,除了循環(huán)還有沒有更好的方式
答:不考慮算法復(fù)雜度,用遞歸做
函數(shù)式編程 map-reduce:
forEach遍歷:
eval
54.假如有一個很長的數(shù)字,怎么給他做千分位的格式化分元呢! (數(shù)字從右往左每三位一個逗號)
答:正則匹配
的下標(biāo),但是foreach循環(huán)中的i表示的是數(shù)組的key是string類型,因為js中一切皆為對象。強烈要求不要用for in 遍歷數(shù)組.
55.什么是塊作用域,什么是函數(shù)作用域?
答:塊作用域:ES5中沒有塊作用域;ES6的塊級作用域,任何一對花括號中的語句集都屬于一個塊,在這之中定義的所有變量在代碼塊外都是不可見的,我們稱之為塊級作用域
函數(shù)作用域:函數(shù)作用域是針對局部變量來說的,在函數(shù)中定義的變量在函數(shù)外不能獲取
56.我聲明了一個構(gòu)造函數(shù),調(diào)用的時候 ?我寫new 和沒有寫new有什么區(qū)別?
答:任何函數(shù),如果不通過 new 操作符來調(diào)用,就是直接執(zhí)行函數(shù)體。
如果使用 new調(diào)用,則不單執(zhí)行函數(shù),還會返回個實例對象。以這種方式調(diào)用構(gòu)造函數(shù)實際上會經(jīng)歷以下4個步驟:
(1) 創(chuàng)建一個新對象;
(2) 將構(gòu)造函數(shù)的作用域賦給新對象(因此 this 就指向了這個新對象);
(3) 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加屬性);
(4) 返回新對象。
57.通過ES5的方法怎么把類數(shù)組轉(zhuǎn)成真正的數(shù)組?
答:方法1:遍歷類數(shù)組,將類數(shù)組里面的元素依次放入一個新的數(shù)組
方法2:使用 apply 和 call,apply方法的第二個參數(shù)是數(shù)組,也可以是類數(shù)組,在調(diào)用的時候會將第二個參數(shù)依次展開
58.簡單說一下事件冒泡
答:IE 的事件流叫做事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深
的那個節(jié)點)接收,然后逐級向上傳播到較為不具體的節(jié)點(文檔)。事件沿 DOM 樹向上傳播,在每一級節(jié)點上都會發(fā)生,直至傳播到 document 對象。
所有現(xiàn)代瀏覽器都支持事件冒泡,但在具體實現(xiàn)上還是有一些差別。IE5.5 及更早版本中的事件冒泡會跳過<html>元素(從<body>直接跳到 document)。IE9、Firefox、Chrome 和 Safari 則將事件一直冒泡到 window 對象。
59.普通函數(shù)和箭頭函數(shù)的this指向的區(qū)別
答:普通函數(shù)this指向由調(diào)用決定,this指向調(diào)用該函數(shù)的對象,而箭頭函數(shù)this指向由定義時決定,this指定父級作用域的this
60.new一個關(guān)鍵字做了哪些事情
答:使用 new 操作符。以這種方式調(diào)用構(gòu)造函數(shù)實際上會經(jīng)歷以下4個步驟:
(1) 創(chuàng)建一個新對象;
(2) 將構(gòu)造函數(shù)的作用域賦給新對象(因此 this 就指向了這個新對象);
(3) 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加屬性);
(4) 返回新對象。
61.有一串手機號,我想把中間的四位替換成****,我要用什么方法實現(xiàn)?
答:利用正則表達(dá)式:
var tel = 15617076160;
tel = "" + tel;
var reg=/(\d{3})\d{4}(\d{4})/;
var newTel = tel.replace(reg, "$1****$2");
console.log(newTel);//156****6160
62.我現(xiàn)在有一個數(shù)組,數(shù)組里面是對象,我要給對象里面的每一項添加一個a:1我要怎么去做呢?
答:
63.循環(huán)的方法有哪些,每個循環(huán)有哪些特點呢?
答:1.for循環(huán):特點是先判斷后執(zhí)行,當(dāng)條件成立才會執(zhí)行,適用于循環(huán)次數(shù)已知的循環(huán);2.while循環(huán):特點也是先判斷后執(zhí)行,當(dāng)條件成立才會執(zhí)行,適用于循環(huán)次數(shù)未知的循環(huán);3.do...while循環(huán):特點是先執(zhí)行后判斷,先執(zhí)行一遍循環(huán)體,再判斷條件是否成立,成立則繼續(xù)循環(huán),不成立則結(jié)束循環(huán)。
64.Async函數(shù)用法和promise區(qū)別
答:簡單的說async函數(shù)就相當(dāng)于自執(zhí)行的Generator函數(shù),相當(dāng)于自帶一個狀態(tài)機,在await的部分等待返回, 返回后自動執(zhí)行下一步。而且相較于Promise,async的優(yōu)越性就是把每次異步返回的結(jié)果從then中拿到最外層的方法中,不需要鏈?zhǔn)秸{(diào)用,只要用同步的寫法就可以了。更加直觀而且,更適合處理并發(fā)調(diào)用的問題。但是async必須以一個Promise對象開始 ,所以async通常是和Promise結(jié)合使用的。總的來說,async函數(shù)主要就是為了解決異步的并發(fā)調(diào)用使用的 ,直接將參數(shù)從then里取出來,相比promise的鏈?zhǔn)秸{(diào)用,傳參更加方便,異步順序更加清晰。
65.Async和promise如何捕捉錯誤信息
答: async可以使用try...catch語句;promise可以使用實例方法catch捕獲異常
66.Extends繼承和js5核心區(qū)別?
答:這道題面試官考查的是你對Es5與ES6繼承的理解,它倆的區(qū)別主要集中在以下幾點:
(1)ES5的繼承實質(zhì)上是先創(chuàng)建子類的實例對象,然后再將父類的方法添加到this上(Parent.apply(this)).
(2)ES6的繼承機制完全不同,實質(zhì)上是先創(chuàng)建父類的實例對象this(所以必須先調(diào)用父類的super()方法),然后再用子類的構(gòu)造函數(shù)修改this。
(3)ES5的繼承時通過原型或構(gòu)造函數(shù)機制來實現(xiàn)。
(4)ES6通過class關(guān)鍵字定義類,里面有構(gòu)造方法,類之間通過extends關(guān)鍵字實現(xiàn)繼承。子類必須在constructor方法中調(diào)用super方法,否則新建實例報錯。因為子類沒有自己的this對象,而是繼承了父類的this對象,然后對其進(jìn)行加工。如果不調(diào)用super方法,子類得不到this對象。
67.Js中如何處理同步和異步的
答:同步的話代碼依次執(zhí)行,異步的處理方式有:(1)回調(diào)函數(shù) (2)promise ?(3)Generator ?(4)Async/await (5)定時器函數(shù) (6)ajax等
68.call?bind?apply?的區(qū)別
答:(1)bind不會立刻執(zhí)行,會返回綁定this之后的函數(shù),call和apply會立即執(zhí)行(2)三者都可以傳參,但是apply是數(shù)組,而call和bind傳過去的是一系列參數(shù)
69.javascript原型和原型鏈
答:原型:每一個javascript對象(除null外)創(chuàng)建的時候,都有一個__proto__屬性指向與之關(guān)聯(lián)另一個對象,這個對象就是我們所說的原型,每一個對象都會從原型中“繼承”屬性。讓我們用一張圖表示構(gòu)造函數(shù)和實例及原型之間的關(guān)系:
原型鏈:每個構(gòu)造函數(shù)都有原型對象,每個構(gòu)造函數(shù)實例都包含一個指向原型對象的內(nèi)部指針(proto),如果我們讓第一個構(gòu)造函數(shù)的原型對象等于第二個構(gòu)造函數(shù)的實例,結(jié)果第一個構(gòu)造函數(shù)的原型對象將包含一個指向第二個原型對象的指針,再然第三個原型對象等于第一個構(gòu)造函數(shù)的實例,這樣第三個原型對象也將包含指向第一個原型對象的指針,以此類推,就夠成了實例于原型的鏈條,這就是原型鏈的基本概念。
70.說說你對spa單頁面應(yīng)用的理解
SPA( single-page application )僅在 Web 頁面初始化時加載相應(yīng)的 HTML、JavaScript 和 CSS。一旦頁面加載完成,SPA 不會因為用戶的操作而進(jìn)行頁面的重新加載或跳轉(zhuǎn);取而代之的是利用路由機制實現(xiàn) HTML 內(nèi)容的變換,UI 與用戶的交互,避免頁面的重新加載。
優(yōu)點:
? 用戶體驗好、快,內(nèi)容的改變不需要重新加載整個頁面,避免了不必要的跳轉(zhuǎn)和重復(fù)渲染;
? 基于上面一點,SPA 相對對服務(wù)器壓力小;
? 前后端職責(zé)分離,架構(gòu)清晰,前端進(jìn)行交互邏輯,后端負(fù)責(zé)數(shù)據(jù)處理;
缺點:
? 初次加載耗時多:為實現(xiàn)單頁 Web 應(yīng)用功能及顯示效果,需要在加載頁面的時候?qū)?JavaScript、CSS 統(tǒng)一加載,部分頁面按需加載;
? 前進(jìn)后退路由管理:由于單頁應(yīng)用在一個頁面中顯示所有的內(nèi)容,所以不能使用瀏覽器的前進(jìn)后退功能,所有的頁面切換需要自己建立堆棧管理;
? SEO 難度較大:由于所有的內(nèi)容都在一個頁面中動態(tài)替換顯示,所以在 SEO 上其有著天然的弱勢。
71.如何是一個對象可迭代
?
總結(jié)
- 上一篇: fcitx重启 linux_fcitx无
- 下一篇: gradle idea java ssm