1稳捆、js數(shù)據(jù)類型
- 基本數(shù)據(jù)類型:Number赠法、String、Boolean乔夯、Null砖织、Undefined、Symbol末荐、bigInt
- 引用數(shù)據(jù)類型:object侧纯、Array、Date甲脏、Function眶熬、RegExp
基本數(shù)據(jù)類型與引用類型在存儲(chǔ)上有什么區(qū)別?
1.存儲(chǔ)位置不同:
基本數(shù)據(jù)類型:以棧的形式存儲(chǔ), 保存與賦值指向數(shù)據(jù)本身, 用typeof 來判斷類型,存儲(chǔ)空間固定妹笆。
引用類型:以堆的形式存儲(chǔ), 保存于賦值指向?qū)ο蟮囊粋€(gè)指針, 用instanceof 來判斷類型 , 存儲(chǔ)空間不固定。
2.傳值方式不同:
基本數(shù)據(jù)類型按值傳遞娜氏,無法改變一個(gè)基本數(shù)據(jù)類型的值
引用類型按引用傳遞拳缠,應(yīng)用類型值可以改變
NaN 是什么
NaN 即非數(shù)值(Not a Number),NaN 屬性用于引用特殊的非數(shù)字值贸弥,該屬性指定的并不是不合法的數(shù)字窟坐。
NaN 屬性 與 Number.Nan 屬性相同。
請(qǐng)使用 isNaN() 來判斷一個(gè)值是否是數(shù)字茂腥。原因是 NaN 與所有值都不相等狸涌,包括它自己。
js中本地對(duì)象最岗?內(nèi)置對(duì)象帕胆?宿主對(duì)象?
本地對(duì)象:ECMA-262 把本地對(duì)象(native object)定義為“獨(dú)立于宿主環(huán)境的 ECMAScript 實(shí)現(xiàn)提供的對(duì)象”般渡。
包含了:Object懒豹、Function、Array驯用、String脸秽、Boolean、Number蝴乔、Date记餐、RegExp、Error薇正、EvalError片酝、RangeError、ReferenceError挖腰、SyntaxError雕沿、TypeError、URIError猴仑。
內(nèi)置對(duì)象:ECMA-262 把內(nèi)置對(duì)象(built-in object)定義為“由 ECMAScript 實(shí)現(xiàn)提供的审轮、獨(dú)立于宿主環(huán)境的所有對(duì)象,在 ECMAScript 程序開始執(zhí)行時(shí)出現(xiàn)”辽俗。這意味著開發(fā)者不必明確實(shí)例化內(nèi)置對(duì)象疾渣,它已被實(shí)例化了。包含了:Gobal 和 Math崖飘。
宿主對(duì)象:由ECMAScript實(shí)現(xiàn)的宿主環(huán)境提供的對(duì)象稳衬,可以理解為:瀏覽器提供的對(duì)象。所有的BOM和DOM都是宿主對(duì)象坐漏。
棧和堆的區(qū)別?
棧(stack):由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值赊琳,局部變量等街夭;
堆(heap):一般由程序員分配釋放,若程序員不釋放躏筏,程序結(jié)束時(shí)可能由操作系統(tǒng)釋放板丽。
描述以下變量的區(qū)別:null,undefined或undeclared
null 表示"沒有對(duì)象"趁尼,即該處不應(yīng)該有值埃碱,轉(zhuǎn)為數(shù)值時(shí)為0。典型用法是:
(1) 作為函數(shù)的參數(shù)酥泞,表示該函數(shù)的參數(shù)不是對(duì)象砚殿。
(2) 作為對(duì)象原型鏈的終點(diǎn)。
undefined 表示"缺少值"芝囤,就是此處應(yīng)該有一個(gè)值似炎,但是還沒有定義,轉(zhuǎn)為數(shù)值時(shí)為NaN悯姊。典型用法是:
(1)變量被聲明了羡藐,但沒有賦值時(shí),就等于undefined悯许。
(2) 調(diào)用函數(shù)時(shí)仆嗦,應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined先壕。
(3)對(duì)象沒有賦值的屬性瘩扼,該屬性的值為undefined。
(4)函數(shù)沒有返回值時(shí)启上,默認(rèn)返回undefined邢隧。
undeclared :js語法錯(cuò)誤,沒有申明直接使用冈在,js無法找到對(duì)應(yīng)的上下文倒慧。
for..in 和 object.keys的區(qū)別
Object.keys不會(huì)遍歷繼承的原型屬性
for...in 會(huì)遍歷繼承的原型屬性
JS中的匿名函數(shù)是什么?
匿名函數(shù):就是沒有函數(shù)名的函數(shù)包券,如:
(function(x, y){ alert(x + y); })(2, 3);
這里創(chuàng)建了一個(gè)匿名函數(shù)(在第一個(gè)括號(hào)內(nèi))纫谅,第二個(gè)括號(hào)用于調(diào)用該匿名函數(shù),并傳入?yún)?shù)溅固。
解釋 JS 中的函數(shù)提升
JS允許將聲明移動(dòng)到頂部的默認(rèn)行為稱為提升付秕。JS中創(chuàng)建函數(shù)的兩種方法是函數(shù)聲明和函數(shù)表達(dá)式。
Js隱式轉(zhuǎn)換介紹
在js中侍郭,當(dāng)運(yùn)算符在運(yùn)算時(shí)询吴,如果兩邊數(shù)據(jù)不統(tǒng)一掠河,CPU就無法計(jì)算,這時(shí)我們編譯器會(huì)自動(dòng)將運(yùn)算符兩邊的數(shù)據(jù)做一個(gè)數(shù)據(jù)類型轉(zhuǎn)換猛计,轉(zhuǎn)成一樣的數(shù)據(jù)類型再計(jì)算
這種無需程序員手動(dòng)轉(zhuǎn)換唠摹,而由編譯器自動(dòng)轉(zhuǎn)換的方式就稱為隱式轉(zhuǎn)換
例如1 > "0"這行代碼在js中并不會(huì)報(bào)錯(cuò),編譯器在運(yùn)算符時(shí)會(huì)先把右邊的"0"轉(zhuǎn)成數(shù)字0`然后在比較大小
隱式轉(zhuǎn)換規(guī)則:
- 轉(zhuǎn)成string類型: +(字符串連接符)
2.轉(zhuǎn)成number類型:++/--(自增自減運(yùn)算符) + - * / %(算術(shù)運(yùn)算符) > < >= <= == != === !=== (關(guān)系運(yùn)算符) - 轉(zhuǎn)成boolean類型:!(邏輯非運(yùn)算符)
2奉瘤、js變量和函數(shù)聲明的提升
- 在js中變量和函數(shù)的聲明會(huì)提升到最頂部執(zhí)行
- 函數(shù)的提升高于變量的提升
- 函數(shù)內(nèi)部如果用 var 聲明了相同名稱的外部變量勾拉,函數(shù)將不再向上尋找。
- 匿名函數(shù)不會(huì)提升盗温。
3藕赞、閉包
閉包的概念:js的作用域中內(nèi)部函數(shù)可以訪問外部函數(shù)的變量,反之則不行卖局,但是我們?yōu)槟軌蜻_(dá)到這一目的斧蜕,就使用內(nèi)部函數(shù)應(yīng)用外部函數(shù)的變量,把該內(nèi)部函數(shù)通過外部函數(shù)return到外部去執(zhí)行吼驶,就形成了閉包惩激。
(就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),基本上就是一個(gè)函數(shù)內(nèi)部返回一個(gè)函數(shù))優(yōu)點(diǎn):
1、可以讀取函數(shù)內(nèi)部的變量
2蟹演、將變量始終保持在內(nèi)存中
3风钻、可以封裝對(duì)象的私有屬性和私有方法
4、避免全局變量的污染缺點(diǎn):
1酒请、較耗費(fèi)內(nèi)存骡技、使用不當(dāng)會(huì)造成內(nèi)存溢出的問題應(yīng)用場(chǎng)景: 防抖(清除舊定時(shí)器,開始新的定時(shí)器)羞反、節(jié)流(上一個(gè)定時(shí)器沒有結(jié)束布朦,則return 不執(zhí)行新的定時(shí)器)、封裝功能時(shí)(需要使用私有的屬性和方法)昼窗、函數(shù)柯里化是趴、給元素偽數(shù)組添加事件需要使用元素的索引值。
Object.is()與原來的比較操作符"==="澄惊、"==” 的區(qū)別唆途?
1)兩等號(hào)判等,會(huì)在比較時(shí)進(jìn)行類型轉(zhuǎn)換掸驱;
2)三等號(hào)判等(判斷嚴(yán)格)肛搬,比較時(shí)不進(jìn)行隱式類型轉(zhuǎn)換,(類 型不同則會(huì)返回false)毕贼;
3)Object.is 在三等號(hào)判等的基礎(chǔ)上特別處理了NaN温赔、-0和+0,保證-0和+0不再相同鬼癣,但Object.is(NaN, NaN)會(huì)返回true陶贼。Object.is應(yīng)被認(rèn)為有其特殊的用途啤贩,而不能用它認(rèn)為它比其它的相等對(duì)比更寬松或嚴(yán)格。
4拜秧、== 和 ===的區(qū)別
==是非嚴(yán)格意義上的相等 值相等就相等
===是嚴(yán)格意義上的相等瓜晤,會(huì)比較兩邊的數(shù)據(jù)類型和值大小 值和引用地址都相等才相等
1、對(duì)于string,number等基礎(chǔ)類型腹纳,==和===有區(qū)別
1)不同類型間比較,==之比較“轉(zhuǎn)化成同一類型后的值”看“值”是否相等驱犹,===如果類型不同嘲恍,其結(jié)果就是不等。
2)同類型比較雄驹,直接進(jìn)行“值”比較佃牛,兩者結(jié)果一樣。
2医舆、對(duì)于Array,Object等高級(jí)類型俘侠,==和===沒有區(qū)別
進(jìn)行“指針地址”比較。
3蔬将、基礎(chǔ)類型與高級(jí)類型爷速,==和===有區(qū)別
1)對(duì)于==,將高級(jí)轉(zhuǎn)化為基礎(chǔ)類型霞怀,進(jìn)行“值”比較惫东。
2)因?yàn)轭愋筒煌?==結(jié)果為false。
5毙石、this
- this總是指向函數(shù)的直接調(diào)用者
- 如果有new關(guān)鍵字廉沮,this指向new出來的對(duì)象
- 在事件中,this指向觸發(fā)這個(gè)事件的對(duì)象
6徐矩、js數(shù)組和對(duì)象的遍歷方式
- for in
- for
- forEach
- for-of
7滞时、map與forEach的區(qū)別
- forEach 方法,是最基本的方法滤灯,就是遍歷與循環(huán)坪稽,默認(rèn)有 3 個(gè)傳參:分別是遍歷的數(shù)組內(nèi)容 item、數(shù)組索引 index力喷、和當(dāng)前遍歷數(shù)組 Array
- map 方法刽漂,基本用法與 forEach 一致,但是不同的弟孟,它會(huì)返回一個(gè)新的數(shù)組贝咙,所以 callback需要有 return 值,如果沒有,會(huì)返回 undefined
8遏匆、箭頭函數(shù)與普通函數(shù)的區(qū)別?
- 函數(shù)體內(nèi)的 this 對(duì)象,就是定義時(shí)所在的對(duì)象漂问,而不是使用時(shí)所在的對(duì)象
- 不可以當(dāng)作構(gòu)造函數(shù)蔼水,也就是說震糖,不可以使用 new 命令,否則會(huì)拋出一個(gè)錯(cuò)誤
- 不可以使用 arguments 對(duì)象趴腋,該對(duì)象在函數(shù)體內(nèi)不存在吊说。如果要用,可以用 Rest 參數(shù)代替
- 不可以使用 yield 命令优炬,因此箭頭函數(shù)不能用作 Generator 函數(shù)
9颁井、同源策略
- 同源指的是域名、協(xié)議蠢护、端口號(hào)相同
10雅宾、如何解決跨域
因?yàn)闉g覽器存在同源策略,協(xié)議+域名+端口 必須完全一致不然就會(huì)受到瀏覽器同源策略限制造成跨域葵硕。
跨域有如下常用方法:
1眉抬、proxy
2、jsonp 原理是利用<script src="https://xxx/a.html?callback=fnName"></script>不是同源策略限制
3懈凹、跨域資源貢獻(xiàn)(CORS)服務(wù)端設(shè)置Access-Control-Allow-Origin即可
4蜀变、window.name + iframe 原理是window.name保存的字符串?dāng)?shù)據(jù)可以跨不同頁面和不同的域
5、h5的postMessage() + window.onmessage() 再不同頁面(或iframe)之間發(fā)送消息和接受消息
6蘸劈、nginx代理 原理是因?yàn)榭缬蚴谴嬖谂c瀏覽器端昏苏,所以通過反向代理通過服務(wù)端獲取數(shù)據(jù)
7、后端在頭部信息里面設(shè)置安全域名
11威沫、嚴(yán)格模式的限制
- 變量必須聲明后再使用
- 函數(shù)的參數(shù)不能有同名屬性贤惯,否則報(bào)錯(cuò)
- 不能使用 with 語句
- 禁止 this 指向全局對(duì)象
12、es6新增
- 新增模板字符串
- 箭頭函數(shù)
- for-of(用來遍歷數(shù)據(jù)—例如數(shù)組中的值棒掠。)
- ES6 將 Promise 對(duì)象納入規(guī)范孵构,提供了原生的 Promise 對(duì)象。
- 增加了 let 和 const 命令烟很,用來聲明變量颈墅。
- 還有就是引入 module 模塊的概念
13、attribute 和 property 的區(qū)別是什么?
- attribute 是 dom 元素在文檔中作為 html 標(biāo)簽擁有的屬性
- property 就是 dom 元素在 js 中作為對(duì)象擁有的屬性雾袱。
- 對(duì)于 html 的標(biāo)準(zhǔn)屬性來說恤筛,attribute 和 property 是同步的,是會(huì)自動(dòng)更新的
- 但是對(duì)于自定義的屬性來說芹橡,他們是不同步的
14毒坛、let和const 的區(qū)別是什么?
- let 命令不存在變量提升,如果在 let 前使用,會(huì)導(dǎo)致報(bào)錯(cuò)
- 如果塊區(qū)中存在 let 和 const 命令煎殷,就會(huì)形成封閉作用域
- 不允許重復(fù)聲明
- const定義的是常量屯伞,不能修改,但是如果定義的是對(duì)象豪直,可以修改對(duì)象內(nèi)部的數(shù)據(jù)
15劣摇、內(nèi)存泄漏
- 定義:程序中己動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放引發(fā)的各種問題。
- js中可能出現(xiàn)的內(nèi)存泄漏情況:結(jié)果:變慢弓乙,崩潰末融,延遲大等
- js中可能出現(xiàn)的內(nèi)存泄漏原因1、全局變量2暇韧、dom 清空時(shí)滑潘,還存在引用3、定時(shí)器未清除4锨咙、子元素存在引起的內(nèi)存泄露
16、script 引入方式?
- html 靜態(tài) <script> 引入
- js 動(dòng)態(tài)插入 <script>
- <script defer> : 異步加載追逮,元素解析完成后執(zhí)行
- <script async> : 異步加載酪刀,但執(zhí)行時(shí)會(huì)阻塞元素渲染
17、數(shù)組(array)方法
- map : 遍歷數(shù)組钮孵,返回回調(diào)返回值組成的新數(shù)組
- forEach : 無法 break 骂倘,可以用 try/catch 中 throw new Error 來停止
- filter : 過濾
- some : 有一項(xiàng)返回 true ,則整體為 true
- every : 有一項(xiàng)返回 false 巴席,則整體為 false
- join : 通過指定連接符生成字符串
- push / pop : 末尾推入和彈出历涝,改變?cè)瓟?shù)組, 返回推入/彈出項(xiàng)
- unshift / shift : 頭部推入和彈出漾唉,改變?cè)瓟?shù)組荧库,返回操作項(xiàng)
- sort(fn) / reverse : 排序與反轉(zhuǎn),改變?cè)瓟?shù)組
- concat : 連接數(shù)組赵刑,不影響原數(shù)組分衫, 淺拷貝
- slice(start, end) : 返回截?cái)嗪蟮男聰?shù)組,不改變?cè)瓟?shù)組
- splice(start,number,value…): 返回刪除元素組成的數(shù)組般此,value 為插入項(xiàng)蚪战,改變?cè)瓟?shù)組
- indexOf / lastIndexOf(value, fromIndex) : 查找數(shù)組項(xiàng),返回對(duì)應(yīng)的下標(biāo)
- reduce / reduceRight(fn(prev, cur) 铐懊,defaultPrev) : 兩兩執(zhí)行邀桑,prev 為上次化簡(jiǎn)函數(shù)的return 值,cur 為當(dāng)前值(從第二項(xiàng)開始)
18科乎、JavaScript 深淺拷貝?
- 淺拷貝:Object.assign
- 深拷貝:可以通過 JSON.parse(JSON.stringify(object)) 來解決
19壁畸、說說異步編程的實(shí)現(xiàn)方式?
- 回調(diào)函數(shù)
優(yōu)點(diǎn):簡(jiǎn)單、容易理解
缺點(diǎn):不利于維護(hù)喜喂、代碼耦合高 - 事件監(jiān)聽
優(yōu)點(diǎn):容易理解瓤摧,可以綁定多個(gè)事件竿裂,每個(gè)事件可以指定多個(gè)回調(diào)函數(shù)
缺點(diǎn):事件驅(qū)動(dòng)型,流程不夠清晰 - 發(fā)布/訂閱(觀察者模式)
類似于事件監(jiān)聽照弥,但是可以通過‘消息中心’腻异,了解現(xiàn)在有多少發(fā)布者,多少訂閱者 - Promise 對(duì)象
優(yōu)點(diǎn):可以利用 then 方法这揣,進(jìn)行鏈?zhǔn)綄懛ɑ诔#豢梢詴鴮戝e(cuò)誤時(shí)的回調(diào)函數(shù)
缺點(diǎn):編寫和理解,相對(duì)比較難 - Generator 函數(shù)
優(yōu)點(diǎn):函數(shù)體內(nèi)外的數(shù)據(jù)交換给赞、錯(cuò)誤處理機(jī)制
缺點(diǎn):流程管理不方便 - async 函數(shù)
優(yōu)點(diǎn):內(nèi)置執(zhí)行器机打、更好的語義、更廣的適用性片迅、返回的是 Promise残邀、結(jié)構(gòu)清晰
缺點(diǎn):錯(cuò)誤處理機(jī)制
20、說說面向?qū)ο缶幊趟枷? - 基本思想是使用對(duì)象柑蛇,類芥挣,繼承,封裝等基本概念來進(jìn)行程序設(shè)計(jì)
- 優(yōu)點(diǎn)1耻台、易維護(hù)2空免、易擴(kuò)展3、開發(fā)工作的重用性盆耽、繼承性高蹋砚,降低重復(fù)工作量。4摄杂、縮短了開發(fā)周期
21坝咐、項(xiàng)目性能優(yōu)化
- 減少 HTTP 請(qǐng)求數(shù)
- 減少 DNS 查詢
- 使用 CDN
- 避免重定向
- 圖片懶加載
- 減少 DOM 元素?cái)?shù)量
- 減少 DOM 操作
- 使用外部 JavaScript 和 CSS
- 壓縮 JavaScript、CSS析恢、字體畅厢、圖片等
- 優(yōu)化 CSS Sprite
- 使用 iconfont
- 多域名分發(fā)劃分內(nèi)容到不同域名
- 盡量減少 iframe 使用
- 避免圖片 src 為空
- 把樣式表放在 link 中
- 把 JavaScript 放在頁面底部
22、什么是單線程氮昧,和異步的關(guān)系框杜?
- 單線程 :只有一個(gè)線程,只能做一件事
- 原因 : 避免 DOM 渲染的沖突袖肥;瀏覽器需要渲染 DOM咪辱;JS 可以修改 DOM 結(jié)構(gòu);JS 執(zhí)行的時(shí)候椎组,瀏覽器 DOM 渲染會(huì)暫停油狂;兩段 JS 也不能同時(shí)執(zhí)行(都修改 DOM 就沖突了);webworker 支持多線程,但是不能訪問 DOM
- 解決方案 :異步
23专筷、說說負(fù)載均衡弱贼?
- 單臺(tái)服務(wù)器共同協(xié)作,不讓其中某一臺(tái)或幾臺(tái)超額工作磷蛹,發(fā)揮服務(wù)器的最大作用
- http 重定向負(fù)載均衡:調(diào)度者根據(jù)策略選擇服務(wù)器以 302 響應(yīng)請(qǐng)求吮旅,缺點(diǎn)只有第一次有效果,后續(xù)操作維持在該服務(wù)器 dns 負(fù)載均衡:解析域名時(shí)味咳,訪問多個(gè) ip 服務(wù)器中的一個(gè)(可監(jiān)控性較弱)原因 - 避免 DOM 渲染的沖突
- 反向代理負(fù)載均衡:訪問統(tǒng)一的服務(wù)器庇勃,由服務(wù)器進(jìn)行調(diào)度訪問實(shí)際的某個(gè)服務(wù)器,對(duì)統(tǒng)一的服務(wù)器要求大槽驶,性能受到 服務(wù)器群的數(shù)量
24责嚷、作用域鏈?
- 作用域鏈可以理解為一組對(duì)象列表掂铐,包含 父級(jí)和自身的變量對(duì)象罕拂,因此我們便能通過作用域鏈訪問到父級(jí)里聲明的變量或者函數(shù)
25、什么是原型全陨、原型鏈聂受、繼承?
- 原型:js中一切皆對(duì)象烤镐,對(duì)象都有一個(gè)隱式的屬性proto,它指向該對(duì)象的原型-prototype(原型對(duì)象)
- 原型鏈:我們調(diào)用對(duì)象的某個(gè)屬性,如果該對(duì)象上沒有該屬性棍鳖,則會(huì)向上在該對(duì)象的原型對(duì)象上找炮叶,有則返回,如果沒有的話繼續(xù)向原型的原型上找渡处,直到Object的原型镜悉,Object的prototype為null,如果沒有找到該屬性則返回undefind医瘫。我們把整個(gè)訪問的過程稱為原型鏈
通過Object.create(null) 創(chuàng)建的對(duì)象沒有原型對(duì)象
26侣肄、JS垃圾回收機(jī)制是怎樣的?
1.概述
- js的垃圾回收機(jī)制是為了防止內(nèi)存泄漏(已經(jīng)不需要的某一塊內(nèi)存還一直存在著)醇份,垃圾回收機(jī)制就是不停歇的尋找這些不再使用的變量稼锅,并且釋放掉它所指向的內(nèi)存。
- 在JS中僚纷,JS的執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存矩距。
2.變量的生命周期
- 當(dāng)一個(gè)變量的生命周期結(jié)束之后,它所指向的內(nèi)存就會(huì)被釋放怖竭。js有兩種變量锥债,局部變量和全局變量,局部變量是在他當(dāng)前的函數(shù)中產(chǎn)生作用,當(dāng)該函數(shù)結(jié)束之后哮肚,該變量內(nèi)存會(huì)被釋放登夫,全局變量的話會(huì)一直存在,直到瀏覽器關(guān)閉為止允趟。
3.js垃圾回收方式
- 有兩種方式: 標(biāo)記清除恼策、引用計(jì)數(shù)
- 標(biāo)記清除:大部分瀏覽器使用這種垃圾回收,當(dāng)變量進(jìn)入執(zhí)行環(huán)境(聲明變量)的時(shí)候拼窥,垃圾回收器將該變量進(jìn)行了標(biāo)記戏蔑,當(dāng)該變量離開環(huán)境的時(shí)候,將其再度標(biāo)記鲁纠,隨之進(jìn)行刪除总棵。
- 引用計(jì)數(shù):這種方式常常會(huì)引起內(nèi)存的泄露,主要存在于低版本的瀏覽器改含。它的機(jī)制就是跟蹤某一個(gè)值得引用次數(shù)情龄,當(dāng)聲明一個(gè)變量并且將一個(gè)引用類型賦值給變量得時(shí)候引用次數(shù)加1,當(dāng)這個(gè)變量指向其他一個(gè)時(shí)引用次數(shù)減1捍壤,當(dāng)為0時(shí)出發(fā)回收機(jī)制進(jìn)行回收骤视。
27、逐進(jìn)增強(qiáng)和優(yōu)雅降級(jí)
- 逐進(jìn)增強(qiáng):針對(duì)低版本瀏覽器進(jìn)行構(gòu)建頁面鹃觉,保證最基本的功能专酗,然后再針對(duì)高版本瀏覽器進(jìn)行效果、交互等改進(jìn)和追加功能達(dá)到更好的用戶體驗(yàn)盗扇。
- 優(yōu)雅降級(jí):一開始就構(gòu)建完整的功能祷肯,然后再針對(duì)低版本瀏覽器進(jìn)行兼容
28、隊(duì)列疗隶、堆佑笋、棧的區(qū)別?
隊(duì)列是先進(jìn)先出:就像一條路斑鼻,有一個(gè)入口和一個(gè)出口蒋纬,先進(jìn)去的就可以先出去。而棧就像一個(gè)箱子坚弱,后放的在上邊蜀备,所以后進(jìn)先出。堆是在程序運(yùn)行時(shí)荒叶,而不是在程序編譯時(shí)琼掠,申請(qǐng)某個(gè)大小的內(nèi)存空間。即動(dòng)態(tài)分配內(nèi)存停撞,對(duì)其訪問和對(duì)一般內(nèi)存的訪問沒有區(qū)別瓷蛙。
棧(Stack)是操作系統(tǒng)在建立某個(gè)進(jìn)程時(shí)或者線程為這個(gè)線程建立的存儲(chǔ)區(qū)域悼瓮。在編程中,例如C/C++中艰猬,所有的局部變量都是從棧中分配內(nèi)存空間横堡,實(shí)際上也不是什么分配,只是從棧頂向上用就行冠桃,在退出函數(shù)的時(shí)候命贴,只是修改棧指針就可以把棧中的內(nèi)容銷毀,所以速度最快食听。
堆(Heap)是應(yīng)用程序在運(yùn)行的時(shí)候請(qǐng)求操作系統(tǒng)分配給自己內(nèi)存胸蛛,一般是申請(qǐng)/給予的過程。由于從操作系統(tǒng)管理的內(nèi)存分配所以在分配和銷毀時(shí)都要占用時(shí)間樱报,所以用堆的效率低的多葬项!但是堆的好處是可以做的很大,C/C++對(duì)分配的Heap是不初始化的迹蛤。
在Java中除了簡(jiǎn)單類型(int,char等)都是在堆中分配內(nèi)存民珍,這也是程序慢的一個(gè)主要原因。但是跟C/C++不同盗飒,Java中分配Heap內(nèi)存是自動(dòng)初始化的嚷量。在Java中所有的對(duì)象(包括int的wrapper Integer)都是在堆中分配的,但是這個(gè)對(duì)象的引用卻是在Stack中分配逆趣。也就是說在建立一個(gè)對(duì)象時(shí)從兩個(gè)地方都分配內(nèi)存蝶溶,在Heap中分配的內(nèi)存實(shí)際建立這個(gè)對(duì)象,而在Stack中分配的內(nèi)存只是一個(gè)指向這個(gè)堆對(duì)象的指針(引用)而已宣渗。
29抖所、什么是線程?進(jìn)程和線程的關(guān)系是什么落包?
線程可定義為進(jìn)程內(nèi)的一個(gè)執(zhí)行單位,或者定義為進(jìn)程內(nèi)的一個(gè)可調(diào)度實(shí)體摊唇。 在具有多線程機(jī)制的操作系統(tǒng)中咐蝇,處理機(jī)調(diào)度的基本單位不是進(jìn)程而是線程。一個(gè)進(jìn)程可以有多個(gè)線程巷查,而且至少有一個(gè)可執(zhí)行線程有序。
打個(gè)比喻:進(jìn)程好比工廠(計(jì)算機(jī))里的車間,一個(gè)工廠里有多個(gè)車間(進(jìn)程)在運(yùn)轉(zhuǎn),每個(gè)車間里有一個(gè)或多個(gè)工人(線程)在協(xié)同工作岛请,這些工人就可以理解為線程旭寿。
線程和進(jìn)程的關(guān)系:
1.線程是進(jìn)程的一個(gè)組成部分.
2.進(jìn)程的多個(gè)線程都在進(jìn)程地址空間活動(dòng).
3.系統(tǒng)資源是分配給進(jìn)程的,線程需要資源時(shí)崇败,系統(tǒng)從進(jìn)程的資源里分配給線程.
4.處理機(jī)調(diào)度的基本單位是線程.
30盅称、使用原生js實(shí)現(xiàn)ajax
創(chuàng)建一個(gè) XMLHttpRequest 對(duì)象肩祥。如果不支持創(chuàng)建該對(duì)象的瀏覽器,則需要?jiǎng)?chuàng)建 ActiveXObject缩膝,具體方法如下:
var xmlHttpRequest;
function createXmlHttpRequest(){
if(window.XMLHttpRequest)//非IE
xmlHttpRequest = new XMLHttpRequest();
else if(window.ActiveObject)//IE6+
xmlHttpRequest = new ActiveObject("Msxml2.XMLHTTP");
else//IE6-
xmlHttpRequest = new ActiveObject("Microsoft.XMLHTTP");
}
提交請(qǐng)求的方法:
open(method,url);//分別為提交的方法(GET或者POST)和提交的url
send(content);
onreadystatechange(){
if(xmlHttpRequest.readyState == 4){
if(xmlHttpRequest.state == 200){
//請(qǐng)求成功
}
}else{
//請(qǐng)求失敗
}
}
字符串的常用方法
- indexOf() 查找某字符串對(duì)應(yīng)的下標(biāo)混狠,如果找不到返回-1
- split(sep) 將字符串按照指定的字符切割成數(shù)組元素,sep表示指定的字符
- slice(start,end) 截取字符串疾层,start開始的下標(biāo)将饺,end結(jié)束的下標(biāo),不包含end本身痛黎;如果end為空截取到最后予弧,如果為負(fù)數(shù)表示倒數(shù)。
- substr(start,count) 截取字符串湖饱,start開始的下標(biāo)掖蛤,count截取的長度,如果count為空截取到最后琉历,如果start為負(fù)值表示倒數(shù)
- substring(start,end) 截取字符串坠七,start開始的下標(biāo),end結(jié)束的下標(biāo)旗笔,不包含end本身彪置,如果end為空截取到最后;如果下標(biāo)為負(fù)數(shù)蝇恶,自動(dòng)轉(zhuǎn)為0
*31拳魁、Set、Map撮弧、和Array的異同潘懊、用法
Set:創(chuàng)建類似數(shù)組的數(shù)據(jù)結(jié)構(gòu),但成員是唯一(基本數(shù)據(jù)類型無重復(fù)贿衍,應(yīng)用數(shù)據(jù)類型可以重復(fù))
常用方法:size()授舟、add()、delete()贸辈、clear()释树、has()可以使用該方法求交集/差集、keys()擎淤、values()奢啥、entries()、forEach()
Map:以鍵值對(duì)的行書存儲(chǔ)數(shù)據(jù)嘴拢,key可以是任何數(shù)據(jù)類型
常用方法:size()桩盲、set(key,value)席吴、get(key)赌结、delete()捞蛋、clear()、has()姑曙、keys()襟交、values()、entries()伤靠、forEach()
Set/Map轉(zhuǎn)Array:
Array.from(set)
const arr = [ ...set ]
const arr = [ ...map.values ]
宏任務(wù)微任務(wù)
js是單線程捣域,但是它有個(gè)事件隊(duì)列機(jī)制來處理異步操作,事件隊(duì)列中有包含宏任務(wù)和微任務(wù)宴合。像常用的setTimeout焕梅,setInterval就是宏任務(wù),Promise()的.then(()=>{})/.catch(()=>{})/.finally(()=>{}) 回調(diào)都是微任務(wù)卦洽。js先執(zhí)行主線程任務(wù)贞言,然后看如果有可以執(zhí)行的微任務(wù)就會(huì)被執(zhí)行,再看如果有宏任務(wù)就被執(zhí)行阀蒂,執(zhí)行完繼續(xù)主線程任務(wù)-然后就一遍一遍這循環(huán)執(zhí)行该窗,這也就是它的事件循環(huán)機(jī)制
深拷貝、淺拷貝
js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型(Number/String/Boolean/Null/undefind)和引用數(shù)據(jù)類型Object(包含F(xiàn)unction
/Array/Date/Regex)蚤霞。淺拷貝對(duì)基本數(shù)據(jù)類型來說拷貝的是值酗失,但對(duì)引用數(shù)據(jù)類型來說拷貝的只是引用, 深拷貝針對(duì)的是引用數(shù)據(jù)類型昧绣,拷貝的是值规肴。
我們常用的拷貝方法有:
- Object.assgin() 僅第一層是深拷貝
- ES6的擴(kuò)展運(yùn)算符(...)僅第一層是深拷貝
- JSON.parse( JSON.stringify(target) ) 會(huì)丟失函數(shù)、會(huì)把時(shí)間對(duì)象變成字符串夜畴、會(huì)把正則對(duì)象變成空對(duì)象
利用遞歸手寫深拷貝方法
function deepClone1(obj) {
var objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
數(shù)組去重
- 利用對(duì)象訪問屬性的方法拖刃,判斷對(duì)象中是否存在key
- 利用reduce方法遍歷數(shù)組,reduce第一個(gè)參數(shù)是遍歷需要執(zhí)行的函數(shù)贪绘,第二個(gè)參數(shù)是item的初始值
var obj={};
var arr=arr.reduce(function(item,next) {
obj[next.key]?'':obj[next.key]=true&&item.push(next);
returnitem;
}, []);
- 利用new Set() 去重兑牡,去重之后可以通過Array.from(set)或者 [...set] 把set轉(zhuǎn)回?cái)?shù)組
cookie sessionstorage localstorage 的異同
相同點(diǎn):都可以存儲(chǔ)數(shù)據(jù)
不同點(diǎn):
存儲(chǔ)大小:cookie 4KB
sessionstorage和localstorage 5MB生命周期:
cookie 可以手動(dòng)設(shè)置過期時(shí)間
sessionstorage 當(dāng)前會(huì)話税灌,關(guān)閉窗口或?yàn)g覽器就被刪除
localstorage 永久保存 除非手動(dòng)刪除使用api:
cookie 操作的是字符串 比較麻煩需要手動(dòng)封裝方法
sessionstorage和localstorang的話有自己的getItem()和setItem()均函、clear()方法,使用起來比較方便
apply()垄琐、call()边酒、bind() 之間的異同
相同點(diǎn):三個(gè)都是改變this指向的经柴。
函數(shù).call(對(duì)象,arg1,arg2....)函數(shù).apply(對(duì)象狸窘,[arg1,arg2,...])var ss=函數(shù).bind(對(duì)象,arg1,arg2,....)區(qū) 別:call()和apply()第一個(gè)參數(shù)是指定的對(duì)象,call()之后的參數(shù)是傳入該函數(shù)的值
apply()第二個(gè)參數(shù)是數(shù)組坯认,數(shù)組中是函數(shù)執(zhí)行需要的參數(shù)
bind()和call()的參數(shù)相同翻擒,不同的是bind()改變this的指向后不會(huì)立即執(zhí)行氓涣,其他兩個(gè)是立即執(zhí)行的
1.第一個(gè)參數(shù)都是指定函數(shù)內(nèi)部中this的指向(函數(shù)執(zhí)行時(shí)所在的作用域),然后根據(jù)指定的作用域陋气,調(diào)用該函數(shù)劳吠。
2.都可以在函數(shù)調(diào)用時(shí)傳遞參數(shù)。call巩趁,bind方法需要直接傳入痒玩,而apply方法需要以數(shù)組的形式傳入。
3.call议慰,apply方法是在調(diào)用之后立即執(zhí)行函數(shù)蠢古,而bind方法沒有立即執(zhí)行,需要將函數(shù)再執(zhí)行一遍别凹。
4.改變this對(duì)象的指向問題不僅有call草讶,apply,bind方法炉菲,也可以使用that變量來固定this的指向堕战。
使用bind()的時(shí)候最好不要直接綁定在Dom上,避免當(dāng)Dom變化時(shí)需要重新綁定
防抖拍霜、節(jié)流函數(shù)
- 防抖:代碼實(shí)現(xiàn)重在清零clearTimeout
function debounce(f, wait) {
lettimer
return (...args) = >{
clearTimeout(timer) timer = setTimeout(() = >{
f(...args)
},
wait)
}
}
- 節(jié)流:代碼實(shí)現(xiàn)重在開鎖關(guān)鎖timer=timeout; timer=null
function throttle(f, wait) {
lettimer
return (...args) = >{
if (timer) {
return
}
timer = setTimeout(() = >{
f(...args)
timer = null
},
wait)
}
}
數(shù)組降維
Array.prototype.concat.apply([],targetArr);
判斷數(shù)據(jù)類型
function toType(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
箭頭函數(shù)和普通function的區(qū)別
1嘱丢、寫法不同
2、this指向不同
function中的this執(zhí)行環(huán)境的不同而不同
箭頭函數(shù)的this是它自己執(zhí)行環(huán)境最近非箭頭函數(shù)的this
3沉御、function可以被new 實(shí)例化屿讽,箭頭函數(shù)不可以
4、function可以被聲明提前吠裆,箭頭函數(shù)不可以伐谈,必須先聲明后使用不然會(huì)報(bào)錯(cuò)
數(shù)組的常用方法
改變?cè)瓟?shù)組的:push()、pop()试疙、unshift()诵棵、shift()、splice() 祝旷、sort()履澳、reverse()
不改變?cè)瓟?shù)組:join()、slice()怀跛、map()距贷、filter()、forEach()吻谋、some()忠蝗、every()、find()漓拾、reduce()
new 操作符具體做了什么
1阁最、創(chuàng)建了一個(gè)空對(duì)象 let obj = {}
2戒祠、繼承了該函數(shù)的原型 obj._ protp_= Fn.prototype
3、改變了該函數(shù)的this指向 let result = Fn.call(obj,...args)
4速种、判斷該函數(shù)的返回值姜盈,如果該返回值是基本數(shù)據(jù)類型則 return obj ,否則 return result
Promise
- 它用于異步操作,它是一個(gè)構(gòu)造函數(shù)配阵,接收一個(gè)回調(diào)函數(shù)馏颂,用于異步計(jì)算,可以將異步操作隊(duì)列化棋傍,按照期望的順序執(zhí)行饱亮,返回符合預(yù)期的結(jié)果而且可以在對(duì)象之間傳遞和操作promise,幫助我們處理隊(duì)列舍沙。
- 有三個(gè)狀態(tài):
1近上、pending[待定]初始狀態(tài)
2、fulfilled[實(shí)現(xiàn)]操作成功
3拂铡、rejected[被否決]操作失敗 - 常用方法:
1壹无、then()、catch()感帅、finally()
2斗锭、all([])接收一個(gè)數(shù)組,當(dāng)所有的異步請(qǐng)求完成之后才完成失球,一旦有某個(gè)異步請(qǐng)求報(bào)錯(cuò)岖是,則直接catch
3、race([])也接收一個(gè)數(shù)組实苞,但它是搶占執(zhí)行豺撑,一旦有一個(gè)異步請(qǐng)求完成就算完成了
函數(shù)柯里化
概念:把一個(gè)接收多個(gè)參數(shù)的函數(shù)變成接收單一參數(shù) 并且返回能夠接收新參數(shù)的函數(shù)
add(1)(2)(3)(4) = 10;
function add(num) {
var sum = num;
var fn = function(v) { sum += v;
return fn
}; fn.toString = function() {
return sum
};
return fn
}
console.log(add(1)(2)(3)(4)) // 10
斐波那契數(shù)列
eg:1、1黔牵、2聪轿、3、5猾浦、8陆错、13...
function fibonacci(n) {
if (n == 1 || n == 2) {
return1
};
returnfibonacci(n - 2) + fibonacci(n - 1);
}
fibonacci(30)
ES5 和 ES6 分別幾種方式聲明變量
- ES5 有倆種:var 和 function
- ES6 有六種:增加四種,let金赦、const音瓷、class 和 import
什么是事件代理/事件委托?
事件代理/事件委托是利用事件冒泡的特性夹抗,將本應(yīng)該綁定在多個(gè)元素上的事件綁定在他們的祖先元素上绳慎,尤其在動(dòng)態(tài)添加子元素的時(shí)候,可以非常方便的提高程序性能,減小內(nèi)存空間偷线。
什么是事件冒泡?什么是事件捕獲沽甥?
冒泡型事件:事件按照從最特定的事件目標(biāo)到最不特定的事件目標(biāo)(document對(duì)象)的順序觸發(fā)声邦。
捕獲型事件:事件從最不精確的對(duì)象(document 對(duì)象)開始觸發(fā),然后到最精確(也可以在窗口級(jí)別捕獲事件摆舟,不過必須由開發(fā)人員特別指定)亥曹。
在添加事件時(shí)用addEventListener(event,fn,useCapture)方法,基中第3個(gè)參數(shù)useCapture是一個(gè)Boolean值恨诱,用來設(shè)置事件是在事件捕獲時(shí)執(zhí)行媳瞪,還是事件冒泡時(shí)執(zhí)行。
注意:IE瀏覽器用attachEvent()方法照宝,此方法沒有相關(guān)設(shè)置蛇受,不過IE的事件模型默認(rèn)是在事件冒泡時(shí)執(zhí)行的,也就是在useCapture等于false的時(shí)候執(zhí)行厕鹃,所以把在處理事件時(shí)把useCapture設(shè)置為false是比較安全兢仰,也實(shí)現(xiàn)兼容瀏覽器的效果。
如何阻止事件冒泡剂碴?
w3c的方法是e.stopPropagation()把将,IE則是使用e.cancelBubble = true。例如:
window.event.cancelBubble = true忆矛;e.stopPropagation();
return false也可以阻止冒泡察蹲。
如何阻止默認(rèn)事件?
w3c的方法是e.preventDefault()催训,IE則是使用e.returnValue = false洽议,比如:
functionstopDefault(e) {
//IE中阻止函數(shù)器默認(rèn)動(dòng)作的方式
if (e && e.preventDefault) e.preventDefault();
else window.event.returnValue = false;
}
return false也能阻止默認(rèn)行為。
DOM 事件有哪些階段漫拭?談?wù)剬?duì)事件代理的理解
分為三大階段:捕獲階段--目標(biāo)階段--冒泡階段
事件代理簡(jiǎn)單說就是:事件不直接綁定到某元素上绞铃,而是綁定到該元素的父元素上,進(jìn)行觸發(fā)事件操作時(shí)(例如'click')嫂侍,再通過條件判斷儿捧,執(zhí)行事件觸發(fā)后的語句(例如'alert(e.target.innerhtml)')
好處:(1)使代碼更簡(jiǎn)潔;(2)節(jié)省內(nèi)存開銷
如何用原生js給一個(gè)按鈕綁定兩個(gè)onclick事件挑宠?
使用addEventListener的方式來綁定多個(gè)事件菲盾。例如
var btn = document.getElementById('btn') btn.addEventListener('click', fn1) btn.addEventListener('click', fn2) functionfn1() {
console.log('我是方法1')
}
functionfn2() {
console.log('我是方法2')
}
響應(yīng)事件有哪些?
onclick鼠標(biāo)點(diǎn)擊某個(gè)對(duì)象各淀;onfocus獲取焦點(diǎn)懒鉴;onblur失去焦點(diǎn);onmousedown鼠標(biāo)被按下等,常用的如下:
1临谱、鼠標(biāo)單擊事件( onclick )
2璃俗、鼠標(biāo)經(jīng)過事件( onmouseover )
3、鼠標(biāo)移開事件( onmouseout )
4悉默、光標(biāo)聚焦事件( onfocus )
5城豁、失焦事件( onblur )
6、內(nèi)容選中事件( onselect )
7抄课、文本框內(nèi)容改變事件( onchange )
8唱星、加載事件( onload )
9、卸載事件( onunload )
造成內(nèi)存泄露的原因
1跟磨、意外的全局變量(在函數(shù)內(nèi)部沒有使用var進(jìn)行聲明的變量)
2间聊、console.log
3、閉包
4抵拘、對(duì)象的循環(huán)引用
5哎榴、未清除的計(jì)時(shí)器
6、DOM泄露(獲取到DOM節(jié)點(diǎn)之后僵蛛,將DOM節(jié)點(diǎn)刪除叹话,但是沒有手動(dòng)釋放變量,拿對(duì)應(yīng)的DOM節(jié)點(diǎn)在變量中還可以訪問到墩瞳,就會(huì)造成泄露)
javascript中this的指向
this永遠(yuǎn)指向函數(shù)運(yùn)行時(shí)所在的對(duì)象溶耘,而不是函數(shù)被創(chuàng)建時(shí)所在的對(duì)象熬甚。
普通的函數(shù)調(diào)用驱敲,函數(shù)被誰調(diào)用鹿霸,this就是誰。
構(gòu)造函數(shù)的話泪电,如果不用new操作符而直接調(diào)用般妙,那即this指向window。用new操作符生成對(duì)象實(shí)例后相速,this就指向了新生成的對(duì)象碟渺。
匿名函數(shù)或不處于任何對(duì)象中的函數(shù)指向window 。
如果是call突诬,apply等苫拍,指定的this是誰,就是誰旺隙。
談?wù)則his的理解
- this總是指向函數(shù)的直接調(diào)用者(而非間接調(diào)用者)
- 如果有new關(guān)鍵字绒极,this指向new出來的那個(gè)對(duì)象
- 在事件中,this指向目標(biāo)元素蔬捷,特殊的是IE的attachEvent中的this總是指向全局對(duì)象window垄提。
eval是做什么的榔袋?
它的功能是把對(duì)應(yīng)的字符串解析成JS代碼并運(yùn)行;應(yīng)該避免使用eval铡俐,不安全凰兑,非常耗性能(2次,一次解析成js語句审丘,一次執(zhí)行)吏够。
Javascript作用鏈域
作用域鏈的原理和原型鏈很類似,如果這個(gè)變量在自己的作用域中沒有备恤,那么它會(huì)尋找父級(jí)的,直到最頂層锦秒。
注意:JS沒有塊級(jí)作用域露泊,若要形成塊級(jí)作用域,可通過(function(){})()旅择;立即執(zhí)行的形式實(shí)現(xiàn)
繼承(6種方式)以及優(yōu)缺點(diǎn)
1.原型鏈繼承
2.構(gòu)造函數(shù)繼承
3.組合繼承(原型鏈繼承+構(gòu)造函數(shù)繼承)
4.原型式繼承
5.寄生繼承
6.組合寄生繼承
請(qǐng)解釋變量聲明提升
通過var聲明的變量會(huì)被提升至作用域的頂端惭笑。不僅僅是變量,函數(shù)聲明也一樣會(huì)被提升生真。
當(dāng)同一作用域內(nèi)同時(shí)出現(xiàn)變量和函數(shù)聲明提升時(shí)沉噩,變量仍然在函數(shù)前面。
函數(shù)聲明與函數(shù)表達(dá)式的區(qū)別柱蟀?
在Javscript中川蒙,解析器在向執(zhí)行環(huán)境中加載數(shù)據(jù)時(shí),對(duì)函數(shù)聲明和函數(shù)表達(dá)式并非是一視同仁的长已,解析器會(huì)率先讀取函數(shù)聲明畜眨,并使其在執(zhí)行任何代碼之前可用(可以訪問),至于函數(shù)表達(dá)式术瓮,則必須等到解析器執(zhí)行到它所在的代碼行康聂,才會(huì)真正被解析執(zhí)行
什么是window對(duì)象? 什么是document對(duì)象?
window對(duì)象代表瀏覽器中打開的一個(gè)窗口。document對(duì)象代表整個(gè)html文檔胞四。實(shí)際上恬汁,document對(duì)象是window對(duì)象的一個(gè)屬性。
document.onload和document.ready兩個(gè)事件的區(qū)別
頁面加載完成有兩種事件
一是ready辜伟,表示文檔結(jié)構(gòu)已經(jīng)加載完成(不包含圖片等非文字媒體文件)
二是onload氓侧,指示頁面包含圖片等文件在內(nèi)的所有元素都加載完成。
Js的淺拷貝和深拷貝
淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針导狡,而不復(fù)制對(duì)象本身甘苍,新舊對(duì)象還是共享同一塊內(nèi)存。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象烘豌,新對(duì)象跟原對(duì)象不共享內(nèi)存载庭,修改新對(duì)象不會(huì)改到原對(duì)象。
淺拷貝
// 第一層為深拷貝Object.assign()Array.prototype.slice()擴(kuò)展運(yùn)算符 ...深拷貝
JSON.parse(JSON.stringify())遞歸函數(shù)
function cloneObject(obj) {
var newObj = {}
//如果不是引用類型,直接返回
if (typeof obj !== 'object') {return obj }
//如果是引用類型囚聚,遍歷屬性
else {for (var attr in obj) {
//如果某個(gè)屬性還是引用類型靖榕,遞歸調(diào)用
newObj[attr] = cloneObject(obj[attr]) } }
return newObj
}
JavaScript里arguments究竟是什么?
Javascrip中國每個(gè)函數(shù)都會(huì)有一個(gè)Arguments對(duì)象實(shí)例arguments顽铸,它引用著函數(shù)的實(shí)參茁计,可以用數(shù)組下標(biāo)的方式"[]"引用arguments的元素。arguments.length為函數(shù)實(shí)參個(gè)數(shù)谓松,arguments.callee引用函數(shù)自身星压。在函數(shù)代碼中,使用特殊對(duì)象arguments鬼譬,開發(fā)者無需明確指出參數(shù)名娜膘,通過使用下標(biāo)就可以訪問相應(yīng)的參數(shù)。
function test() {
var s = ""; for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]); s += arguments[i] + ","; }return s;
}
test("name", "age");//name,age arguments雖然有一些數(shù)組的性質(zhì)优质,但其并非真正的數(shù)組竣贪,只是一個(gè)類數(shù)組對(duì)象。其并沒有數(shù)組的很多方法巩螃,不能像真正的數(shù)組那樣調(diào)用.jion(),.concat(),.pop()等方法演怎。
**什么是"use strict";?使用它的好處和壞處分別是什么?**
在代碼中出現(xiàn)表達(dá)式-"use strict"; 意味著代碼按照嚴(yán)格模式解析避乏,這種模式使得Javascript在更嚴(yán)格的條件下運(yùn)行爷耀。
好處:
* 消除Javascript語法的一些不合理、不嚴(yán)謹(jǐn)之處拍皮,減少一些怪異行為;
* 消除代碼運(yùn)行的一些不安全之處畏纲,保證代碼運(yùn)行的安全;
* 提高編譯器效率春缕,增加運(yùn)行速度盗胀;
* 為未來新版本的Javascript做好鋪墊。
壞處:
同樣的代碼锄贼,在"嚴(yán)格模式"中票灰,可能會(huì)有不一樣的運(yùn)行結(jié)果;
一些在"正常模式"下可以運(yùn)行的語句宅荤,在"嚴(yán)格模式"下將不能運(yùn)行屑迂。
**解釋什么是Json**
* JSON 是一種輕量級(jí)的數(shù)據(jù)交換格式。
* JSON 獨(dú)立于語言和平臺(tái)冯键,JSON 解析器和 JSON 庫支持許多不同的編程語言惹盼。
* JSON的語法表示三種類型值,簡(jiǎn)單值(字符串惫确,數(shù)值手报,布爾值蚯舱,null),數(shù)組,對(duì)象
**緩存策略**
1掩蛤、強(qiáng)緩存:
強(qiáng)緩存兩個(gè)相關(guān)字段:【Expires】-過期時(shí)間枉昏,【Cache-Control】-過期時(shí)長。
強(qiáng)緩存分為兩種情況揍鸟,一種是發(fā)送HTTP請(qǐng)求兄裂,一種不需要發(fā)送。
首先檢查強(qiáng)緩存阳藻,這個(gè)階段不需要發(fā)送HTTP請(qǐng)求晰奖,通過查找不同的字段來進(jìn)行,不同的HTTP版本不同
http1.0版本腥泥,使用的是expires匾南,http1.1使用的是cache-control
expires即過期時(shí)間,時(shí)間是相對(duì)于服務(wù)器的時(shí)間而言的道川,存在于服務(wù)端返回的響應(yīng)頭中午衰,在這個(gè)過期時(shí)間之· 前可以直接從緩存里面獲取數(shù)據(jù)立宜,無需再次請(qǐng)求冒萄。
cache-control,http1.1版本中橙数,使用的是這字段尊流,這個(gè)字段采用的時(shí)間是過期時(shí)長,對(duì)應(yīng)的是max-age
注意點(diǎn):當(dāng)expires和cache-control同時(shí)存在時(shí)灯帮,優(yōu)先考慮cache-control崖技。
當(dāng)緩存資源失效了,也就是沒有命中強(qiáng)緩存钟哥,接下來就進(jìn)入?yún)f(xié)商緩存
2迎献、協(xié)商緩存
強(qiáng)緩存失效后,瀏覽器在請(qǐng)求頭中攜帶響應(yīng)的緩存etag來向服務(wù)器發(fā)送請(qǐng)求腻贰,服務(wù)器根據(jù)對(duì)應(yīng)的tag吁恍,來決定是否使用緩存。
分為兩種播演,【last-modified】和【etag】冀瓦。兩者個(gè)有優(yōu)勢(shì)
last-modified:這個(gè)字段表示的是【最后修改時(shí)間】,在瀏覽器第一次個(gè)服務(wù)器發(fā)送請(qǐng)求后写烤,服務(wù)器會(huì)在響應(yīng)頭中加上這個(gè)字段翼闽。瀏覽器接收到后,【如果再次請(qǐng)求】洲炊,會(huì)在請(qǐng)求頭中攜帶 if-modified-since 這個(gè)字段感局,這個(gè)字段的值也就是服務(wù)器傳來的最后修改時(shí)間尼啡。服務(wù)器拿到請(qǐng)求頭中的 if-modified-since 的字段后,其實(shí)會(huì)和這個(gè)服務(wù)器中 該資源的最后修改時(shí)間 做對(duì)比:
如果請(qǐng)求頭中的這個(gè)值小于最后修改時(shí)間蓝厌,說明要更新了玄叠,返回新的資源,跟常規(guī)的http請(qǐng)求響應(yīng)的流程一樣拓提,否則返回304读恃,告訴瀏覽器直接使用緩存。
etag:etag是服務(wù)器根據(jù)當(dāng)前文件的內(nèi)容代态,對(duì)文件生成唯一的標(biāo)識(shí)寺惫,比如md5算法,只要里面的內(nèi)容有改動(dòng)蹦疑,這個(gè)值就會(huì)修改西雀,服務(wù)器通過響應(yīng)頭把這個(gè)字段給瀏覽器。瀏覽器接收到etag值歉摧,會(huì)在下次請(qǐng)求的時(shí)候艇肴,將這個(gè)值作為【if-none-match】這個(gè)字段的內(nèi)容,發(fā)送給服務(wù)器叁温。服務(wù)器接收到這個(gè)【if-none-match】字段后再悼,會(huì)跟服務(wù)器上該資源的【etag】進(jìn)行比較。
如果兩者一樣的話膝但,直接返回304冲九,告訴瀏覽器直接使用緩存,如果不一樣的話跟束,說明內(nèi)容更新了莺奸,返回新的資源,跟常規(guī)的http請(qǐng)求響應(yīng)的流程一樣冀宴。
**22灭贷、301、302略贮、303甚疟、304狀態(tài)碼有什么區(qū)別**
301表示永久重定向,請(qǐng)求的資源分配了新的url
302表示臨時(shí)重定向刨肃,請(qǐng)求的資源分配了新的url,本次暫且使用新的url,下次請(qǐng)求可能會(huì)改變
303表示請(qǐng)求的資源路徑發(fā)生改變古拴,使用GET方法請(qǐng)求新url。她與302的功能一樣真友,但是明確指出使用GET方法請(qǐng)求新url黄痪。
304表示請(qǐng)求的資源未更新。該狀態(tài)碼不應(yīng)該認(rèn)為是一種錯(cuò)誤盔然,而是對(duì)客戶端有緩存情況下服務(wù)端的一種響應(yīng)桅打。
tips:新url指的是是嗜,第一次請(qǐng)求返回的location
**深度優(yōu)先、廣度優(yōu)先**
深度優(yōu)先遍歷:對(duì)每一個(gè)可能的分支路徑深入到不能再深入為止挺尾,而且每個(gè)結(jié)點(diǎn)只能訪問一次鹅搪。遞歸
要特別注意的是,二叉樹的深度優(yōu)先遍歷比較特殊遭铺,可以細(xì)分為先序遍歷丽柿、中序遍歷、后序遍歷(我們前面使用的是先序遍歷)魂挂。具體說明如下:
先序遍歷:對(duì)任一子樹甫题,先訪問根,然后遍歷其左子樹涂召,最后遍歷其右子樹坠非。
中序遍歷:對(duì)任一子樹,先遍歷其左子樹果正,然后訪問根炎码,最后遍歷其右子樹。
后序遍歷:對(duì)任一子樹秋泳,先遍歷其左子樹潦闲,然后遍歷其右子樹,最后訪問根轮锥。
廣度優(yōu)先遍歷:又叫層次遍歷矫钓,從上往下對(duì)每一層依次訪問要尔,在每一層中舍杜,從左往右(也可以從右往左)訪問結(jié)點(diǎn),訪問完一層就進(jìn)入下一層赵辕,直到?jīng)]有結(jié)點(diǎn)可以訪問為止 遍歷
**前端安全方面有沒有了解既绩?XSS和CSRF如何攻防?**
> **XSS(Cross Site Scripting)**是跨站腳本攻擊还惠,為了區(qū)分CSS饲握,所以縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼蚕键,當(dāng)用戶瀏覽該頁之時(shí)救欧,嵌入其中Web里面的Script代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的目的锣光。
> 在網(wǎng)頁的一些公共區(qū)域(例如笆怠,建議提交表單或消息公共板的輸入表單)輸入一些文本,這些文本被其它用戶看到誊爹,但這些文本不僅僅是他們要輸入的文本蹬刷,同時(shí)還包括一些可以在客戶端執(zhí)行的腳本瓢捉。如:
<script>alert(document.cookie);</script>
在文本框中輸入以上代碼,然后點(diǎn)擊提交办成,就會(huì)把用戶的cookie彈出來泡态。
> **XSS漏洞修復(fù)**
1.將重要的cookies標(biāo)記為HTTP ONLY。
2.只允許用戶輸入我們期望的數(shù)據(jù)迂卢。如年齡框只能輸入數(shù)字某弦。
3.對(duì)數(shù)據(jù)進(jìn)行HTTP Encode處理。
4.過濾或者移除特殊的HTML標(biāo)簽而克。
5.過濾JS事件的標(biāo)簽刀崖。
> **CSRF(Cross-site request forgery)**是跨站請(qǐng)求偽造。XSS利用站點(diǎn)內(nèi)的信任用戶拍摇,而CSRF則通過偽裝來自受信任用戶的請(qǐng)求來利用受信任的網(wǎng)站亮钦。其實(shí)就是攻擊者盜用了你的身份,以你的名義發(fā)送惡意請(qǐng)求充活。
**CSRF攻擊的思想**
用戶瀏覽并登陸信任網(wǎng)站A蜂莉;通過驗(yàn)證,在用戶處產(chǎn)生X的cookie混卵;用戶在沒有登出X的時(shí)候映穗,瀏覽危險(xiǎn)網(wǎng)站B;B要求訪問第三方網(wǎng)站A幕随,發(fā)出一個(gè)請(qǐng)求蚁滋;根據(jù)這個(gè)請(qǐng)求,瀏覽器使用剛才產(chǎn)生的cookie直接訪問A赘淮。
**一個(gè)簡(jiǎn)單的實(shí)例**
銀行網(wǎng)站A辕录,它以GET請(qǐng)求來完成銀行轉(zhuǎn)賬的操作,如:[http://www.mybank.com/Transfer.php?toBankId=11&money=1000](http://www.mybank.com/Transfer.php?toBankId=11&money=1000)
危險(xiǎn)網(wǎng)站B梢卸,它里面有一段HTML的代碼如下:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
首先走诞,你登錄了銀行網(wǎng)站A,然后訪問危險(xiǎn)網(wǎng)站B蛤高,噢蚣旱,這時(shí)你會(huì)發(fā)現(xiàn)你的銀行賬戶少了1000塊......
**CSRF的防御**
1.在表單里增加Hash值,以認(rèn)證這確實(shí)是用戶發(fā)送的請(qǐng)求戴陡,然后在服務(wù)器端進(jìn)行Hash值驗(yàn)證塞绿。
2.驗(yàn)證碼:每次的用戶提交都需要用戶在表單中填寫一個(gè)圖片上的隨機(jī)字符串。
#### 20恤批、說說你對(duì)HTML5認(rèn)識(shí)?(是什么,為什么)
> HTML5指的是包括 HTML 异吻、 CSS 和 JavaScript 在內(nèi)的一套技術(shù)組合。 HTML5 是 HTML 最新版本开皿, 2014 年 10 月由萬維網(wǎng)聯(lián)盟( W3C )完成標(biāo)準(zhǔn)制定涧黄。
HTML4陳舊不能滿足日益發(fā)展的互聯(lián)網(wǎng)需要篮昧,特別是移動(dòng)互聯(lián)網(wǎng)。為了增強(qiáng)瀏覽器功能 Flash 被廣泛使用笋妥,但安全與穩(wěn)定堪憂懊昨,不適合在移動(dòng)端使用(耗電、觸摸春宣、不開放)酵颁。
HTML5增強(qiáng)了瀏覽器的原生功能,符合 HTML5 規(guī)范的瀏覽器功能將更加強(qiáng)大月帝,減少了 Web 應(yīng)用對(duì)插件的依賴躏惋,讓用戶體驗(yàn)更好,讓開發(fā)更加方便嚷辅,另外 W3C 從推出 HTML4.0 到 5.0 之間共經(jīng)歷了 17 年簿姨, HTML 的變化很小,這并不符合一個(gè)好產(chǎn)品的演進(jìn)規(guī)則簸搞。
**什么是WebGL,它有什么優(yōu)點(diǎn)?**
> WebGL(全寫 Web Graphics Library )是一種 3D 繪圖標(biāo)準(zhǔn)扁位,這種繪圖技術(shù)標(biāo)準(zhǔn)允許把 JavaScript 和 OpenGL ES 2.0 結(jié)合在一起,通過增加OpenGL ES 2.0 的一個(gè) JavaScript 綁定趁俊, WebGL 可以為 HTML5 Canvas 提供硬件 3D 加速渲染域仇,這樣 Web 開發(fā)人員就可以借助系統(tǒng)顯卡來在瀏覽器里更流暢地展示 3D 場(chǎng)景和模型了,還能創(chuàng)建復(fù)雜的導(dǎo)航和數(shù)據(jù)視覺化寺擂。顯然暇务, WebGL 技術(shù)標(biāo)準(zhǔn)免去了開發(fā)網(wǎng)頁專用渲染插件的麻煩,可被用于創(chuàng)建具有復(fù)雜 3D 結(jié)構(gòu)的網(wǎng)站頁面怔软,甚至可以用來設(shè)計(jì) 3D 網(wǎng)頁游戲等等垦细。
> **WebGL完美地解決了現(xiàn)有的 Web 交互式三維動(dòng)畫的兩個(gè)問題:**
> **第一,它通過HTML腳本本身實(shí)現(xiàn) Web 交互式三維動(dòng)畫的制作爽雄,無需任何瀏覽器插件支持 ;**
> **第二蝠检,它利用底層的圖形硬件加速功能進(jìn)行的圖形渲染沐鼠,是通過統(tǒng)一的挚瘟、標(biāo)準(zhǔn)的、跨平臺(tái)的OpenGL接口實(shí)現(xiàn)的饲梭。**
> **通俗說WebGL中 canvas 繪圖中的 3D 版本乘盖。因?yàn)樵?WebGL 很復(fù)雜,我們經(jīng)常會(huì)使用一些三方的庫憔涉,如 three.js 等订框,這些庫多數(shù)用于HTML5 游戲開發(fā)。**
**說說你對(duì)SVG理解?**
> SVG可縮放矢量圖形( Scalable Vector Graphics )是基于可擴(kuò)展標(biāo)記語言( XML )兜叨,用于描述二維矢量圖形的一種圖形格式穿扳。 SVG 是W3C('World Wide Web ConSortium' 即 ' 國際互聯(lián)網(wǎng)標(biāo)準(zhǔn)組織 ') 在 2000 年 8 月制定的一種新的二維矢量圖形格式衩侥,也是規(guī)范中的網(wǎng)絡(luò)矢量圖形標(biāo)準(zhǔn)。 SVG 嚴(yán)格遵從 XML 語法矛物,并用文本格式的描述性語言來描述圖像內(nèi)容茫死,因此是一種和圖像分辨率無關(guān)的矢量圖形格式。 SVG 于 2003 年 1 月14 日成為 W3C 推薦標(biāo)準(zhǔn)履羞。
> **特點(diǎn):**
> **(1)任意放縮**
> **用戶可以任意縮放圖像顯示峦萎,而不會(huì)破壞圖像的清晰度、細(xì)節(jié)等忆首。**
> **(2)文本獨(dú)立**
> **SVG圖像中的文字獨(dú)立于圖像爱榔,文字保留可編輯和可搜尋的狀態(tài)。也不會(huì)再有字體的限制糙及,用戶系統(tǒng)即使沒有安裝某一字體详幽,也會(huì)看到和他們制作時(shí)完全相同的畫面。**
> **(3)較小文件**
> **總體來講浸锨,SVG文件比那些 GIF 和 JPEG 格式的文件要小很多妒潭,因而下載也很快。**
> **(4)超強(qiáng)顯示效果**
> **SVG圖像在屏幕上總是邊緣清晰揣钦,它的清晰度適合任何屏幕分辨率和打印分辨率雳灾。**
> **(5)超級(jí)顏色控制**
> **SVG圖像提供一個(gè) 1600 萬種顏色的調(diào)色板,支持 ICC 顏色描述文件標(biāo)準(zhǔn)冯凹、 RGB 谎亩、線 X 填充、漸變和蒙版宇姚。**
> **(6)交互 X 和智能化匈庭。 SVG 面臨的主要問題一個(gè)是如何和已經(jīng)占有重要市場(chǎng)份額的矢量圖形格式 Flash 競(jìng)爭(zhēng)的問題,另一個(gè)問題就是 SVG 的本地運(yùn)行環(huán)境下的廠家支持程度浑劳。**
**介紹一下webpack*
webpack是模塊打包機(jī)(自動(dòng)化構(gòu)建工具)阱持,我們常用webpack構(gòu)建我們的項(xiàng)目框架。在webpack中魔熏,包含entry衷咽,output,mode蒜绽,module镶骗,plugin,module中我們一般會(huì)引入各種loader幫助我們翻譯編譯代碼躲雅,(loader是從右往左執(zhí)行)plugin會(huì)引入各種插件鼎姊,優(yōu)化構(gòu)建出來的代碼,mode是模式,一般分為development和production相寇。entry是入口慰于,output是出口。