摘要:箭頭函數(shù)與傳統(tǒng)函數(shù)的區(qū)別,主要集中在以下方面沒(méi)有和綁定,這些值由最近一層非箭頭函數(shù)決定。不能通過(guò)關(guān)鍵字調(diào)用,所以不能用作構(gòu)造函數(shù),否則程序會(huì)拋出錯(cuò)誤。聲明的全局變量不是全局對(duì)象的屬性。
本文首發(fā)于我的博客:http://blog.dunizb.com
原文鏈接:http://blog.dunizb.com/2017/09/08/interview-questions-2017/轉(zhuǎn)載聲明
最近發(fā)現(xiàn)有人和網(wǎng)站盜用我的文章,有的轉(zhuǎn)載卻自己標(biāo)為原創(chuàng),沒(méi)有明確顯示原文作者、原文出處及原文鏈接。我的網(wǎng)絡(luò)ID是:Dunizb。請(qǐng)自覺(jué)遵守網(wǎng)絡(luò)文章轉(zhuǎn)載規(guī)范以及開(kāi)源協(xié)議。
想知道自己什么水平就出去面試,拋磚引玉,詳細(xì)答案還需要自己去補(bǔ)充....
更新記錄
2019-07-28更新:修改第13題RESTful API的答案
2018-06-12更新:修改第1題答案
2017-10-19更新:修改22題深淺拷貝的答案
2017-10-18更新:修正部分題目答案,答案并非十分準(zhǔn)確,僅供參考,此文部分題目答案故意省掉了一些高精尖、新奇特的東西,比如創(chuàng)建對(duì)象我寫了三種,《JS高程》上可不止三種,一切以常用記得住的為宗旨,所以,對(duì)于部分答案有疑問(wèn)的同學(xué),可以留言討論或自行斟酌
2017-10-12更新:有部分題目屬于后端范疇,或者是大前端范疇,因?yàn)槲乙郧白鯦ava后端的(關(guān)于我),故偶爾會(huì)遇到后端相關(guān)的一些問(wèn)題,但是沒(méi)有遇到問(wèn)純Java技術(shù)問(wèn)題。如果你對(duì)某些后端題目不理解就直接跳過(guò)吧。
金九銀十,在九月之前把工作落實(shí)了,經(jīng)歷了好幾個(gè)公司的面試,得到一些信息,和大家分享:
大部分公司(創(chuàng)業(yè)公司)都趨向于招一個(gè)牛逼的前端而不是三四個(gè)平庸的前端
性能優(yōu)化、ES6必問(wèn)
招聘要求上清一色的要求有一門后端語(yǔ)言的經(jīng)驗(yàn)
招聘要求寫的和面試相關(guān)性并不是很高
以下是我整理我面試遇到的一些我覺(jué)得具有代表性的題目,剛好30題,吐血獻(xiàn)上!
0.談?wù)剬?duì)前端安全的理解,有什么,怎么防范前端安全問(wèn)題主要有XSS、CSRF攻擊
XSS:跨站腳本攻擊
它允許用戶將惡意代碼植入到提供給其他用戶使用的頁(yè)面中,可以簡(jiǎn)單的理解為一種javascript代碼注入。
XSS的防御措施:
過(guò)濾轉(zhuǎn)義輸入輸出
避免使用eval、new Function等執(zhí)行字符串的方法,除非確定字符串和用戶輸入無(wú)關(guān)
使用cookie的httpOnly屬性,加上了這個(gè)屬性的cookie字段,js是無(wú)法進(jìn)行讀寫的
使用innerHTML、document.write的時(shí)候,如果數(shù)據(jù)是用戶輸入的,那么需要對(duì)象關(guān)鍵字符進(jìn)行過(guò)濾與轉(zhuǎn)義
CSRF:跨站請(qǐng)求偽造
其實(shí)就是網(wǎng)站中的一些提交行為,被黑客利用,在你訪問(wèn)黑客的網(wǎng)站的時(shí)候進(jìn)行操作,會(huì)被操作到其他網(wǎng)站上
CSRF防御措施:
檢測(cè)http referer是否是同域名
避免登錄的session長(zhǎng)時(shí)間存儲(chǔ)在客戶端中
關(guān)鍵請(qǐng)求使用驗(yàn)證碼或者token機(jī)制
其他的一些攻擊方法還有HTTP劫持、界面操作劫持
1.使用箭頭函數(shù)需要注意的地方當(dāng)要求動(dòng)態(tài)上下文的時(shí)候,你就不能使用箭頭函數(shù),比如:定義方法,用構(gòu)造器創(chuàng)建對(duì)象,處理時(shí)間時(shí)用 this 獲取目標(biāo)。
箭頭函數(shù)與傳統(tǒng)函數(shù)的區(qū)別,主要集中在以下方面:
沒(méi)有this、super、arguments 和 new.target 綁定,這些值由最近一層非箭頭函數(shù)決定。
不能通過(guò) new 關(guān)鍵字調(diào)用,所以不能用作構(gòu)造函數(shù),否則程序會(huì)拋出錯(cuò)誤(SyntaxError)。
沒(méi)有原型。由于不可以通過(guò)new 關(guān)鍵字調(diào)用箭頭函數(shù),因而沒(méi)有構(gòu)建原型的需求,所以箭頭函數(shù)不存在 prototype 這個(gè)屬性。
不可以改變 this 的綁定,函數(shù)內(nèi)部的 this 值不可以被改變,在函數(shù)的生命周期內(nèi)始終保持一致。
不支持 arguments 對(duì)象,所以你必須通過(guò)命名參數(shù)和不定參數(shù)這兩種形式訪問(wèn)函數(shù)的參數(shù)。
不支持重復(fù)的命名參數(shù),無(wú)論在嚴(yán)格還是非嚴(yán)格模式下都不支持,而在傳統(tǒng)的函數(shù)規(guī)定中只有在嚴(yán)格模式下才不能有重復(fù)的命名參數(shù)。
2.webpack.load的原理loaders是你用在app源碼上的轉(zhuǎn)換元件。他們是用node.js運(yùn)行的,把源文件作為參數(shù),返回新的資源的函數(shù)。
3.ES6 let、constlet
let是更完美的var
let聲明的變量擁有塊級(jí)作用域,let聲明仍然保留了提升的特性,但不會(huì)盲目提升。
let聲明的全局變量不是全局對(duì)象的屬性。不可以通過(guò)window.變量名的方式訪問(wèn)
形如for (let x…)的循環(huán)在每次迭代時(shí)都為x創(chuàng)建新的綁定
let聲明的變量直到控制流到達(dá)該變量被定義的代碼行時(shí)才會(huì)被裝載,所以在到達(dá)之前使用該變量會(huì)觸發(fā)錯(cuò)誤。
const
定義常量值,不可以重新賦值,但是如果值是一個(gè)對(duì)象,可以改變對(duì)象里的屬性值
const OBJ = {"a":1, "b":2}; OBJ.a = 3; OBJ = {};// 重新賦值,報(bào)錯(cuò)! console.log(OBJ.a); // 34.CSS3 box-sizing的作用
設(shè)置CSS盒模型為標(biāo)準(zhǔn)模型或IE模型。標(biāo)準(zhǔn)模型的寬度只包括content,二IE模型包括border和padding
box-sizing屬性可以為三個(gè)值之一:
content-box,默認(rèn)值,border和padding不計(jì)算入width之內(nèi)
padding-box,padding計(jì)算入width內(nèi)
border-box,border和padding計(jì)算入width之內(nèi)
5.說(shuō)說(shuō)HTML5中有趣的標(biāo)簽(新標(biāo)簽及語(yǔ)義化)如果代碼寫的語(yǔ)義化,有利于SEO。搜索引擎就會(huì)很容易的讀懂該網(wǎng)頁(yè)要表達(dá)的意思。例如文本模塊要有大標(biāo)題,合理利用h1-h6,列表形式的代碼使用ul或ol,重要的文字使用strong等等??傊褪且浞掷酶鞣NHTML標(biāo)簽完成他們本職的工作
6.git命令,如何批量刪除分支git branch |grep "branchName" |xargs git branch -D,從分支列表中匹配到指定分支,然后一個(gè)一個(gè)(分成小塊)傳遞給刪除分支的命令,最后進(jìn)行刪除。(參考這里)
7.創(chuàng)建對(duì)象的三種方法第一種方式,字面量
var o1 = {name: "o1"}
第二種方式,通過(guò)構(gòu)造函數(shù)
var o2 = new Object({name: "o2"}) var M = function(name){ this.name = name } var o3 = new M("o3")
第三種方式,Object.create
var p = {name: "p"} var o4 = Object.create(p)
新創(chuàng)建的對(duì)o4的原型就是p,同時(shí)o4也擁有了屬性name
8.JS實(shí)現(xiàn)繼承的幾種方式借用構(gòu)造函數(shù)實(shí)現(xiàn)繼承
function Parent1(){ this.name = "parent1" } function Child1(){ Parent1.call(this); this.type = "child1"; }
缺點(diǎn):Child1無(wú)法繼承Parent1的原型對(duì)象,并沒(méi)有真正的實(shí)現(xiàn)繼承(部分繼承)
借用原型鏈實(shí)現(xiàn)繼承
function Parent2(){ this.name = "parent2"; this.play = [1,2,3]; } function Child2(){ this.type = "child2"; } Child2.prototype = new Parent2();
缺點(diǎn):原型對(duì)象的屬性是共享的
組合式繼承
function Parent3(){ this.name = "parent3"; this.play = [1,2,3]; } function Child3(){ Parent3.call(this); this.type = "child3"; } Child3.prototype = Object.create(Parent3.prototype); Child3.prototype.constructor = Child3;9.當(dāng)new Foo()時(shí)發(fā)生了什么
1.創(chuàng)建了一個(gè)新對(duì)象
2.將新創(chuàng)建的空對(duì)象的隱式原型指向其構(gòu)造函數(shù)的顯示原型。
3.將this指向這個(gè)新對(duì)象
4.如果無(wú)返回值或者返回一個(gè)非對(duì)象值,則將新對(duì)象返回;如果返回值是一個(gè)新對(duì)象的話那么直接直接返回該對(duì)象。
參考《JS高程》6.2.2
雪碧圖,移動(dòng)端響應(yīng)式圖片,靜態(tài)資源CDN,減少Dom操作(事件代理、fragment),壓縮JS和CSS、HTML等,DNS預(yù)解析
11.瀏覽器渲染原理首先來(lái)看一張圖:
HTML被解析成DOM Tree,CSS被解析成CSS Rule Tree
把DOM Tree和CSS Rule Tree經(jīng)過(guò)整合生成Render Tree(布局階段)
元素按照算出來(lái)的規(guī)則,把元素放到它該出現(xiàn)的位置,通過(guò)顯卡畫到屏幕上
更多詳情看這里12.前端路由的原理
什么是路由?簡(jiǎn)單的說(shuō),路由是根據(jù)不同的 url 地址展示不同的內(nèi)容或頁(yè)面
使用場(chǎng)景?前端路由更多用在單頁(yè)應(yīng)用上, 也就是SPA, 因?yàn)閱雾?yè)應(yīng)用, 基本上都是前后端分離的, 后端自然也就不會(huì)給前端提供路由。
前端的路由和后端的路由在實(shí)現(xiàn)技術(shù)上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現(xiàn)之前,前端的路由都是通過(guò) hash 來(lái)實(shí)現(xiàn)的,hash 能兼容低版本的瀏覽器。
兩種實(shí)現(xiàn)前端路由的方式
HTML5 History兩個(gè)新增的API:history.pushState 和 history.replaceState,兩個(gè) API 都會(huì)操作瀏覽器的歷史記錄,而不會(huì)引起頁(yè)面的刷新。
Hash就是url 中看到 # ,我們需要一個(gè)根據(jù)監(jiān)聽(tīng)哈希變化觸發(fā)的事件( hashchange) 事件。我們用 window.location 處理哈希的改變時(shí)不會(huì)重新渲染頁(yè)面,而是當(dāng)作新頁(yè)面加到歷史記錄中,這樣我們跳轉(zhuǎn)頁(yè)面就可以在 hashchange 事件中注冊(cè) ajax 從而改變頁(yè)面內(nèi)容。
優(yōu)點(diǎn)
從性能和用戶體驗(yàn)的層面來(lái)比較的話,后端路由每次訪問(wèn)一個(gè)新頁(yè)面的時(shí)候都要向服務(wù)器發(fā)送請(qǐng)求,然后服務(wù)器再響應(yīng)請(qǐng)求,這個(gè)過(guò)程肯定會(huì)有延遲。而前端路由在訪問(wèn)一個(gè)新頁(yè)面的時(shí)候僅僅是變換了一下路徑而已,沒(méi)有了網(wǎng)絡(luò)延遲,對(duì)于用戶體驗(yàn)來(lái)說(shuō)會(huì)有相當(dāng)大的提升。
更多內(nèi)容請(qǐng)看這里
缺點(diǎn)
使用瀏覽器的前進(jìn),后退鍵的時(shí)候會(huì)重新發(fā)送請(qǐng)求,沒(méi)有合理地利用緩存。
RESTful API是指符合REST設(shè)計(jì)風(fēng)格的Web API,為了使的接口安全、易用、可維護(hù)以及可擴(kuò)張,一般設(shè)計(jì)RESTful API需要考慮以下幾個(gè)方面:
通信用HTTPS安全協(xié)議
在URL中加入版本號(hào)
URL中的路徑不能有動(dòng)詞,只能用名詞
用HTTP方法對(duì)資源進(jìn)行增刪改查的操作
用HTTP狀態(tài)嗎傳達(dá)執(zhí)行結(jié)果和失敗原因
為集合提供過(guò)濾、排序、分頁(yè)功能
用查詢字符串或HTTP首部Accpet進(jìn)行內(nèi)容協(xié)商,指定返回結(jié)果的數(shù)據(jù)格式
及時(shí)更新文檔,每個(gè)接口都有對(duì)應(yīng)的說(shuō)明
14.script標(biāo)簽的defer、async的區(qū)別defer是在HTML解析完之后才會(huì)執(zhí)行,如果是多個(gè),按照加載的順序依次執(zhí)行
async是在加載完成后立即執(zhí)行,如果是多個(gè),執(zhí)行順序和加載順序無(wú)關(guān)
什么是同源策略?
限制從一個(gè)源加載的文檔或腳本如何與來(lái)自另一個(gè)源的資源進(jìn)行交互。
一個(gè)源指的是主機(jī)名、協(xié)議和端口號(hào)的組合,必須相同
跨域通信的幾種方式
JSONP
Hash
postMessage
WebSocket
CORS
JSONP原理
基本原理:利用script標(biāo)簽的異步加載特性實(shí)現(xiàn)
給服務(wù)端傳一個(gè)回調(diào)函數(shù),服務(wù)器返回一個(gè)傳遞過(guò)去的回調(diào)函數(shù)名稱的JS代碼
更多請(qǐng)查看:《前后端通信類知識(shí)》16.作用域與閉包、原型相關(guān)問(wèn)題 16.1 作用域
域表示的就是范圍,即作用域,就是一個(gè)名字在什么地方可以使用,什么時(shí)候不能使用。
簡(jiǎn)單的說(shuō),作用域是針對(duì)變量的,比如我們創(chuàng)建一個(gè)函數(shù) a1,函數(shù)里面又包了一個(gè)子函數(shù) a2。
// 全局作用域 functiona a1() { // a1作用域 function a2() { // a2作用域 } }
此時(shí)就存 在三個(gè)作用域:全局作用域,a1 作用域,a2 作用域;即全局作用域包含了 a1 的作用域,a2 的作用域包含了 a1 的作用域。
當(dāng) a2 在查找變量的時(shí)候會(huì)先從自身的作用域區(qū)查找,找不到再到上一級(jí) a1 的作用域查找,如果還沒(méi)找到就到全局作用域區(qū)查找,這樣就形成了一個(gè)作用域鏈。
16.2 閉包什么是閉包?
當(dāng)一個(gè)內(nèi)部函數(shù)被其外部函數(shù)之外的變量引用時(shí),就形成了一個(gè)閉包。
簡(jiǎn)單的來(lái)說(shuō),所謂的閉包就是一個(gè)具有封閉的對(duì)外不公開(kāi)的,包裹結(jié)構(gòu)或空間。
為什么函數(shù)可以構(gòu)成閉包?
閉包就是一個(gè)具有封閉與包裹功能的結(jié)構(gòu),是為了實(shí)現(xiàn)具有私有訪問(wèn)空間的函數(shù)的。函數(shù)可以構(gòu)成閉包。函數(shù)內(nèi)部定義的數(shù)據(jù)函數(shù)外部無(wú)法訪問(wèn),即函數(shù)具有封閉性;函數(shù)可以封裝代碼即具有包裹性,所以函數(shù)可以構(gòu)成閉包。
閉包的作用,就是保存自己私有的變量,通過(guò)提供的接口(方法)給外部使用,但外部不能直接訪問(wèn)該變量。
當(dāng)我們需要在模塊中定義一些變量,并希望這些變量一直保存在內(nèi)存中但又不會(huì)“污染”全局的變量時(shí),就可以用閉包來(lái)定義這個(gè)模塊。
閉包的缺點(diǎn):閉包的缺點(diǎn)就是常駐內(nèi)存,會(huì)增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。
函數(shù)套函數(shù)就是閉包嗎?:不是!,當(dāng)一個(gè)內(nèi)部函數(shù)被其外部函數(shù)之外的變量引用時(shí),才會(huì)形成了一個(gè)閉包。
16.4 閉包的基本模型對(duì)象模式
函數(shù)內(nèi)部定義個(gè)一個(gè)對(duì)象,對(duì)象中綁定多個(gè)函數(shù)(方法),返回對(duì)象,利用對(duì)象的方法訪問(wèn)函數(shù)內(nèi)的數(shù)據(jù)
function createPerson() { var __name__ = ""; return { getName: function () { return __name__; }, setName: function( value ) { // 如果不姓張就報(bào)錯(cuò) if ( value.charAt(0) === "張" ) { __name__ = value; } else { throw new Error( "姓氏不對(duì),不能取名" ); } } } } var p = createPerson(); p.set_Name( "張三豐" ); console.log( p.get_Name() ); p.set_Name( "張王富貴" ); console.log( p.get_Name() );
函數(shù)模式
函數(shù)內(nèi)部定義一個(gè)新函數(shù),返回新函數(shù),用新函數(shù)獲得函數(shù)內(nèi)的數(shù)據(jù)
function foo() { var num = Math.random(); function func() { return mun; } return func; } var f = foo(); // f 可以直接訪問(wèn)這個(gè) num var res1 = f(); var res2 = f();
沙箱模式
沙箱模式就是一個(gè)自調(diào)用函數(shù),代碼寫到函數(shù)中一樣會(huì)執(zhí)行,但是不會(huì)與外界有任何的影響,比如jQuery
(function () { var jQuery = function () { // 所有的算法 } // .... // .... jQuery.each = function () {} window.jQuery = window.$ = jQuery; })(); $.each( ... )原型
原型是什么
原型就是一個(gè)普通的對(duì)象,每個(gè)對(duì)象都有一個(gè)原型(Object除外),原型能存儲(chǔ)我們的方法,構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例對(duì)象能夠引用原型中的方法。
查看原型
以前一般使用對(duì)象的__proto__屬性,ES6推出后,推薦用Object.getPrototypeOf()方法來(lái)獲取對(duì)象的原型
什么是原型鏈?
凡是對(duì)象就有原型,那么原型又是對(duì)象,因此凡是給定一個(gè)對(duì)象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構(gòu)成一個(gè)對(duì)象的序列,稱該結(jié)構(gòu)為原型鏈。
更多內(nèi)容請(qǐng)看這里17.如何進(jìn)行錯(cuò)誤監(jiān)控
前端錯(cuò)誤的分類
即時(shí)運(yùn)行錯(cuò)誤(代碼錯(cuò)誤)
資源加載錯(cuò)誤
錯(cuò)誤的捕獲方式
即時(shí)運(yùn)行錯(cuò)誤的捕獲方式:
try...catch
window.onerror
資源加載錯(cuò)誤:
object.onerror(如img,script)
performance.getEntries()
Error事件捕獲
延伸:跨域的js運(yùn)行錯(cuò)誤可以捕獲嗎,錯(cuò)誤提示什么,應(yīng)該怎么處理?
可以。
Script error
1.在script標(biāo)簽增加crossorigin屬性
2.設(shè)置js資源響應(yīng)頭Access-Control-Allow-Orgin:*
上報(bào)錯(cuò)誤的基本原理
采用Ajax通信方式上報(bào)
利用Image對(duì)象上報(bào)
DOM事件的級(jí)別
DOM0,element.onclick = function(){}
DOM2,element.addEventListener("click", function(){}, false);
DOM事件模型是什么:指的是冒泡和捕獲
DOM事件流是什么:捕獲階段 -> 目標(biāo)階段 -> 冒泡階段
描述DOM事件捕獲的具體流程
window --> document --> documentElement(html標(biāo)簽) --> body --> .... --> 目標(biāo)對(duì)象
Event對(duì)象常見(jiàn)應(yīng)用
event.preventDefault(),阻止默認(rèn)行為
event.stopPropagation(),阻止事件冒泡
event.stopImmediatePropagation(),阻止剩余的事件處理函數(shù)執(zhí)行并且防止事件冒泡到DOM樹(shù)上,這個(gè)方法不接受任何參數(shù)。
event.currentTarget,返回綁定事件的元素
event.target,返回觸發(fā)事件的元素
如何自定義事件
Event,不能傳遞參數(shù)
var eve = new Event("自定義事件名"); ev.addEventListener("自定義事件名", function(){ console.log("自定義事件") }); ev.dispatchEvent(eve);
CustomEvent,還可以指定參數(shù)
19.本地起了一個(gè)http server,為什么只能在同一個(gè)WIFI(局域網(wǎng))上訪問(wèn)?你沒(méi)有公網(wǎng)IP當(dāng)然就不能被外網(wǎng)訪問(wèn)了。常見(jiàn)的WIFI情況下,一般的ip會(huì)是~192.168.0.x·這樣的,只是對(duì)局域網(wǎng)(同WIFI下)可見(jiàn),但是外網(wǎng)是訪問(wèn)不了的。(segmentfault上的答案)
20.回流和重繪參考《如何寫出高性能DOM?》
21.數(shù)組去重的方法參考:《JavaScript數(shù)組去重》
22.深拷貝與淺拷貝是什么
淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存(內(nèi)存區(qū)域沒(méi)有隔離)。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存(內(nèi)存區(qū)域隔離),修改新對(duì)象不會(huì)改到原對(duì)象。在多層對(duì)象上,淺拷貝只拷貝一層
淺拷貝舉例
var Chinese = { nation:"中國(guó)" }; var Doctor ={ career:"醫(yī)生" } function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } var Doctor = extendCopy(Chinese); Doctor.career = "醫(yī)生"; alert(Doctor.nation); // 中國(guó)
深拷貝舉例
function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === "object") { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; }
參考文章:阮一峰:Javascript面向?qū)ο缶幊蹋ㄈ悍菢?gòu)造函數(shù)的繼承
深拷貝實(shí)現(xiàn)方式
手動(dòng)復(fù)制方式,如上面的代碼,缺點(diǎn)就是
Object.assign,ES6 的新函數(shù),可以幫助我們達(dá)成跟上面一樣的功能。
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = Object.assign({}, obj1); obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- 沒(méi)被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }
轉(zhuǎn)成 JSON 再轉(zhuǎn)回來(lái)
用JSON.stringify把對(duì)象轉(zhuǎn)成字符串,再用JSON.parse把字符串轉(zhuǎn)成新的對(duì)象。
缺點(diǎn):只有可以轉(zhuǎn)成JSON格式的對(duì)象才可以這樣用,像function沒(méi)辦法轉(zhuǎn)成JSON。
jquery,有提供一個(gè)$.extend可以用來(lái)做 Deep Copy。
lodash,也有提供_.cloneDeep用來(lái)做 Deep Copy。
遞歸實(shí)現(xiàn)深拷貝
function clone( o ) { var temp = {}; for( var k in o ) { if( typeof o[ k ] == "object" ){ temp[ k ] = clone( o[ k ] ); } else { temp[ k ] = o[ k ]; } } return temp; }
參考文章:關(guān)于 JS 中的淺拷貝和深拷貝,進(jìn)擊JavaScript之(四)玩轉(zhuǎn)遞歸與數(shù)列
23.如何快速合并雪碧圖Gulp:gulp-css-spriter
webpack:optimize-css-assets-webpack-plugin
Go!Png
在線工具
24.代碼優(yōu)化基本方法減少HTTP請(qǐng)求
HTML優(yōu)化:
使用語(yǔ)義化標(biāo)簽
減少iframe:iframe是SEO的大忌,iframe有好處也有弊端
避免重定向
CSS優(yōu)化:
布局代碼寫前面
刪除空樣式
不濫用浮動(dòng),字體,需要加載的網(wǎng)絡(luò)字體根據(jù)網(wǎng)站需求再添加
選擇器性能優(yōu)化
避免使用表達(dá)式,避免用id寫樣式
js優(yōu)化:
壓縮
減少重復(fù)代碼
圖片優(yōu)化:
使用WebP
圖片合并,CSS sprite技術(shù)
減少DOM操作
緩存已經(jīng)訪問(wèn)過(guò)的元素
"離線"更新節(jié)點(diǎn), 再將它們添加到樹(shù)中
避免使用 JavaScript 輸出頁(yè)面布局--應(yīng)該是 CSS 的事兒
使用JSON格式來(lái)進(jìn)行數(shù)據(jù)交換
使用CDN加速
使用HTTP緩存:添加 Expires 或 Cache-Control 信息頭
使用DNS預(yù)解析
Chrome內(nèi)置了DNS Prefetching技術(shù), Firefox 3.5 也引入了這一特性,由于Chrome和Firefox 3.5本身對(duì)DNS預(yù)解析做了相應(yīng)優(yōu)化設(shè)置,所以設(shè)置DNS預(yù)解析的不良影響之一就是可能會(huì)降低Google Chrome瀏覽器及火狐Firefox 3.5瀏覽器的用戶體驗(yàn)。
預(yù)解析的實(shí)現(xiàn):
用meta信息來(lái)告知瀏覽器, 當(dāng)前頁(yè)面要做DNS預(yù)解析:
在頁(yè)面header中使用link標(biāo)簽來(lái)強(qiáng)制對(duì)DNS預(yù)解析:
25.HTTPS的握手過(guò)程瀏覽器將自己支持的一套加密規(guī)則發(fā)送給服務(wù)器。
服務(wù)器從中選出一組加密算法與HASH算法,并將自己的身份信息以證書的形式發(fā)回給瀏覽器。證書里面包含了網(wǎng)站地址,加密公鑰,以及證書的頒發(fā)機(jī)構(gòu)等信息。
瀏覽器獲得網(wǎng)站證書之后瀏覽器要做以下工作:
驗(yàn)證證書的合法
如果證書受信任,或者是用戶接受了不受信的證書,瀏覽器會(huì)生成一串隨機(jī)數(shù)的密碼,并用證書中提供的公鑰加密。
使用約定好的HASH算法計(jì)算握手消息,并使用生成的隨機(jī)數(shù)對(duì)消息進(jìn)行加密,最后將之前生成的所有信息發(fā)送給服務(wù)器
網(wǎng)站接收瀏覽器發(fā)來(lái)的數(shù)據(jù)之后要做以下的操作:
使用自己的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發(fā)來(lái)的握手消息,并驗(yàn)證HASH是否與瀏覽器發(fā)來(lái)的一致。
使用密碼加密一段握手消息,發(fā)送給瀏覽器。
瀏覽器解密并計(jì)算握手消息的HASH,如果與服務(wù)端發(fā)來(lái)的HASH一致,此時(shí)握手過(guò)程結(jié)束,之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對(duì)稱加密算法進(jìn)行加密。
參考文章:《HTTPS 工作原理和 TCP 握手機(jī)制》
26.BFC相關(guān)問(wèn)題BFC(Block formatting context)直譯為"塊級(jí)格式化上下文"。它是一個(gè)獨(dú)立的渲染區(qū)域,只有 Block-level box 參 與, 它規(guī)定了內(nèi)部的 Block-level Box 如何布局,并且與這個(gè)區(qū)域外部毫不相干。
BFC的渲染特點(diǎn)
BFC這個(gè)元素的垂直方向的邊距會(huì)發(fā)生重疊,垂直方向的距離由margin決定,取最大值
BFC的區(qū)域不會(huì)與浮動(dòng)元素的box重疊(清除浮動(dòng)原理)
計(jì)算BFC的高度的時(shí)候,浮動(dòng)元素也會(huì)參與計(jì)算
哪些元素會(huì)生成 BFC
BFC 就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素。反之也如此。
根元素
overflow不為visible
float不為none
position為absolute或fixed
display為inline-block、table-cell、table-caption、flex、inline-flex
BFC的使用場(chǎng)景
他的很常用的一個(gè)應(yīng)用場(chǎng)景就是解決邊距重疊、清楚浮動(dòng)的問(wèn)題.
27.響應(yīng)式圖片1.JS或者服務(wù)端硬編碼,resize事件,判斷屏幕大小加載不同的圖片
2.img srcset 方法
3.picture標(biāo)簽 -> source
4.svg
5.第三方庫(kù)polyfill
var a = []; // 1.基于instanceof a instanceof Array; // 2.基于constructor a.constructor === Array; // 3.基于Object.prototype.isPrototypeOf Array.prototype.isPrototypeOf(a); // 4.基于getPrototypeOf Object.getPrototypeOf(a) === Array.prototype; // 5.基于Object.prototype.toString Object.prototype.toString.apply(a) === "[object Array]"; // 6.Array.isArray Array.isArray([]); // true
以上,除了Object.prototype.toString外,其它方法都不能正確判斷變量的類型。
29.UTF-8和Unicode的區(qū)別UTF-8就是在互聯(lián)網(wǎng)上使用最廣的一種unicode的實(shí)現(xiàn)方式。
Unicode的出現(xiàn)是為了統(tǒng)一地區(qū)性文字編碼方案,為解決unicode如何在網(wǎng)絡(luò)上傳輸?shù)膯?wèn)題,于是面向傳輸?shù)谋姸?UTF(UCS Transfer Format)標(biāo)準(zhǔn)出現(xiàn)了,顧名思義,UTF-8就是每次8個(gè)位傳輸數(shù)據(jù),而UTF-16就是每次16個(gè)位。
ASCII --> 地區(qū)性編碼(GBK) --> Unicode --> UTF-8
知乎參考回答
參考
慕課網(wǎng)實(shí)戰(zhàn)課程《前端跳槽面試必備技巧》
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/51239.html
摘要:箭頭函數(shù)與傳統(tǒng)函數(shù)的區(qū)別,主要集中在以下方面沒(méi)有和綁定,這些值由最近一層非箭頭函數(shù)決定。不能通過(guò)關(guān)鍵字調(diào)用,所以不能用作構(gòu)造函數(shù),否則程序會(huì)拋出錯(cuò)誤。聲明的全局變量不是全局對(duì)象的屬性。 showImg(https://segmentfault.com/img/remote/1460000013229911?w=2402&h=1398); 本文首發(fā)于我的博客:http://blog.du...
摘要:箭頭函數(shù)與傳統(tǒng)函數(shù)的區(qū)別,主要集中在以下方面沒(méi)有和綁定,這些值由最近一層非箭頭函數(shù)決定。不能通過(guò)關(guān)鍵字調(diào)用,所以不能用作構(gòu)造函數(shù),否則程序會(huì)拋出錯(cuò)誤。聲明的全局變量不是全局對(duì)象的屬性。 showImg(https://segmentfault.com/img/remote/1460000013229911?w=2402&h=1398); 本文首發(fā)于我的博客:http://blog.du...
摘要:一些知識(shí)點(diǎn)有哪些方法方法前端從入門菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集前端掘金前端從入門菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集歸屬于筆者的前端入門與最佳實(shí)踐。 工欲善其事必先利其器-前端實(shí)習(xí)簡(jiǎn)歷篇 - 掘金 有幸認(rèn)識(shí)很多在大廠工作的學(xué)長(zhǎng),在春招正式開(kāi)始前為我提供很多內(nèi)部推薦的機(jī)會(huì),非常感謝他們對(duì)我的幫助。現(xiàn)在就要去北京了,對(duì)第一份正式的實(shí)習(xí)工作也充滿期待,也希望把自己遇到的一些問(wèn)題和...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
閱讀 2373·2021-11-18 10:07
閱讀 2330·2021-09-22 15:59
閱讀 3088·2021-08-23 09:42
閱讀 2287·2019-08-30 15:44
閱讀 1201·2019-08-29 15:06
閱讀 2324·2019-08-29 13:27
閱讀 1224·2019-08-29 13:21
閱讀 1423·2019-08-29 13:13