1.var ,let 和const的區(qū)別:
let和const是es6新增的語法, let和var都可以定義變量,但是二者作用域不同突倍,let有塊級作用域妖滔,var沒有。所以在var變量值會存在變量提升現(xiàn)在氢惋,而let不會洞翩;const是定義常量稽犁。
2.typeof返回類型:
區(qū)分值類型和引用類型;
值類型: Number骚亿,String已亥,Boolean,Undefined来屠,Symbol
引用類型:Object虑椎,function,null(typeof null === 'object')
所以typeof的返回值為?Number的妖,String绣檬,Boolean,Undefined嫂粟,Symbol Object娇未,function。常見的強(qiáng)制類型轉(zhuǎn)換parseInt,parseFloat,toString星虹。常見的隱式類型轉(zhuǎn)換:拼接字符串零抬, == ,等等宽涌;
3.數(shù)組slice和splice區(qū)別:
slice: slice(startIndex, endIndex),如果傳入一個參數(shù)平夜,默認(rèn)從startIndex剪切到endIndex = (arr.lenght-1);
splice: splice(startIndex, number, string),和slice類似,但是只限于類似卸亮。第一個參數(shù)是起始位置忽妒,第二個參數(shù)是需要剪切的數(shù)量,第三個參數(shù)是你需要插入數(shù)組中的內(nèi)容兼贸。也可以設(shè)置第二個參數(shù)為0段直,不剪切數(shù)據(jù),直接插入數(shù)據(jù)溶诞,和數(shù)組的常用方法(push, pop,unshift,shift)聯(lián)系起來鸯檬。
兩者最大的區(qū)別就是slice是純函數(shù),splice是非純函數(shù)螺垢;
4.[10, 20, 30].map(parseInt)輸出內(nèi)容是什么喧务?
[10, 20, 30].map(parseInt) 等價于[10, 20, 30].map( (item, index) => { return parseInt(item, index)});所以問題等價于返回的數(shù)組中的值是什么枉圃?parseInt(10, 0) = 10; parseInt(20, 1) = NaN; parseInt(30, 2) = NaN;
5.get請求和post請求之間的區(qū)別功茴?
1.get一般請求url地址查詢,post一般提交表單操作讯蒲;
2.get參數(shù)拼接在url上痊土,受url長度限制;post請求放在請求體內(nèi)墨林,所以post請求數(shù)據(jù)體積可以較大赁酝;
3.安全性: post易于防止CSRF攻擊(cross-site request forgery跨站偽請求犯祠,偽造你的信息,向服務(wù)器發(fā)送請求酌呆,竊取賬號密碼)衡载;
6.call, apply, bind的區(qū)別?
三者都是改變函數(shù)this的指向隙袁,call和apply只是參數(shù)傳遞有區(qū)別:call(this, a1, a2, a3, ...), apply(this, argument) argument是數(shù)組或者偽數(shù)組(或者說是集合)痰娱;call和bind的區(qū)別:bind返回一個函數(shù)對象;
7.事件的委托(代理):
事件的委托(代理)是通過事件的冒泡實現(xiàn)的菩收,事件的冒泡可以理解為由下向上觸發(fā)父級元素事件的一個過程(氣泡會受到浮力梨睁,從下往上運動)。給父級元素綁定事件娜饵,可以通過子元素來觸發(fā)坡贺,這就是事件委托(代理)。
8.函數(shù)閉包和閉包的特性箱舞,有何負(fù)面影響遍坟?
函數(shù)和對其周圍狀態(tài)(lexical environment,詞法環(huán)境)的引用捆綁在一起構(gòu)成閉包(closure)晴股。也就是說愿伴,閉包可以讓你從內(nèi)部函數(shù)訪問外部函數(shù)作用域。在 JavaScript 中电湘,每當(dāng)函數(shù)被創(chuàng)建隔节,就會在函數(shù)生成時生成閉包。(MDN官方介紹?https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures)
閉包的特性:函數(shù)作為參數(shù)或者返回值寂呛。閉包會占用內(nèi)存官帘,得不到釋放。(自由變量的查找是在函數(shù)定義的地方昧谊,而不是函數(shù)使用的地方)。
9.阻止事件冒泡和默認(rèn)行為的方法酗捌?
阻止冒泡:event.stoppropagation呢诬;阻止默認(rèn)行為:event.preventdefault;
10.如何減少DOM操作胖缤?
1.緩存DOM的查詢結(jié)果
2.多次DOM操作合并到一次(Fragment)
11.函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別尚镰?
函數(shù)表達(dá)式:const fn = function () { };函數(shù)聲明:function fn () { };兩者的區(qū)別就是函數(shù)表達(dá)式會預(yù)解析(頁面加載時會提前解析函數(shù)聲明,函數(shù)聲明寫在邏輯后面哪廓,也會執(zhí)行生效)狗唉,而函數(shù)表達(dá)式不會。
12.new Object( )和Object.creat( )區(qū)別涡真?
new Object( ) === { }分俯;我們習(xí)慣于 const obj = { }這中寫法肾筐,其實這種寫法等于 const obj = new Object ( )。new Object ( )的原型指向于Object.prototype缸剪,即obj.__proto__ === Object.prototype吗铐。Object.creat(null)是沒有原型的(Object.prototype.__proto__? === null),但是Object.creat({ })可以指定原型杏节。
例如:const obj1 = { }; const obj2 = Object.creat(obj1);??obj2.__proto__ === obj1
13.關(guān)于this:
this指向其實就是作用域和調(diào)用對象的問題唬渗。
14.手寫字符串trim方法:
trim是去除字符串開頭或結(jié)尾處的空格的方法。例如 const? str = '? hello? '; console.log(str.trim()) = 'hello';
為了保證兼容性奋渔,我們可以使用正則表達(dá)式的方式改寫trim方法:
String.prototype.trim_ =function(str) {
????return str.replace(/^\s+/, '').replace(/\s+$/, '');
}
(^表示開頭镊逝,\s表示空格,+表示一個或多個嫉鲸,$表示結(jié)尾)
15.求數(shù)組中的最大值
方法有多種:
1.簡單暴力:直接調(diào)用Api撑蒜。Math.max()
2.利用數(shù)組的sort()方法,然后去最后一位數(shù)充坑。(sort()方法是用來排序的减江,按從小到大的順序),arr.sort([...])[arr.length - 1]
3.利用forEach循環(huán)捻爷,(map也行辈灼,但是map返回值是默認(rèn)是數(shù)組,所以如return的值要修改)
const arr = [];
let max =arr[0];
arr.forEach( item => max = max < item ? max = item :max)
4.利用for循環(huán):
const arr = [];
let max =arr[0];
for (let i =0; i < arr.length; i ++) {
max < arr[i] ? max = arr[i] : max
}
5.冒泡算法
16.如何實現(xiàn)繼承也榄?
ES6中新增的class方法巡莹,extends和super關(guān)鍵字就可以實現(xiàn)繼承。ES5可以通過prototype實現(xiàn)繼承甜紫。
17.如何捕獲js程序中的異常降宅?
1.手動捕獲異常:try{ },catch{ }囚霸,finally{ }方法腰根。一般會在異步調(diào)用的時候用到。(promise函數(shù)拓型。promise函數(shù)是同步额嘿,then方法才是異步)
2.自動捕獲異常:通過window.onerror = function(message,source劣挫,lineNum册养,colNum,error) { } (對于跨域的js压固,如cdn球拦,沒有詳細(xì)的報錯原因;對于壓縮的js,還要配合sourcemap反查到未壓縮的行坎炼、列)愧膀。
18.獲取當(dāng)前頁面url參數(shù)
有兩種方式:
1.這里需要用到bom中l(wèi)ocation的一個api:location.search(BOM: location, navigator, screen,history)。通過location.search我們可以拿到url的參數(shù)(包括問號点弯,所以需要用substr方法進(jìn)行修改)扇调。
function getUrl() {
const str =location.search.substring(1);//拿到問號后面的字符串。例如:抢肛?id=666&&name=zhangsan => //id=666&&name=zhangsan
? ? const value = str.split('&&').map( item => {/*map是純函數(shù)方法狼钮,返回一個數(shù)組,如果用forEach會顯示undefined捡絮,因為forEach沒有返回值 */
????????????const arr = item.split('=');//把=切割熬芜,返回一個數(shù)組,包含兩個元素
? ? ????????? ? const key = arr[0];//把數(shù)組的第一項復(fù)制給key
? ? ? ????????? const value = arr[1];//把數(shù)組的第二項賦值給value
? ? ? ? ????return { key, value }
????????})
}
2.第二種是直接使用URLSearchParams
function getUrl(url) {
const str =location.search;
? ? const paras =new URLSearchParams(str);//URLSearchParams是一個class構(gòu)造函數(shù)
? ? paras.get(url)
}
3.使用正則表達(dá)式
19.數(shù)組排平(flatten)比如:[1, 2, 5, [1, 2, 5], 7] 變成[1, 2, 5, 1, 2, 5, 7]福稳,[1, [2, 3, 4], [1, [ 2, 3, [ 4, 5] ] ], 6] = [ 1, 2, 4, 5, 1, 2, 3, 4, 5, 6]
首先這個問題肯定涉及到數(shù)組合并的問題涎拉,concat()方法是肯定需要使用的。Array.prototype.concat.apply([ ], arr)這句代碼的意思就是合并arr數(shù)組里面的數(shù)組的圆,但是只會合并兩層(例如:Array.prototype.concat.apply([ ], [1, [2, 3])? === [1, 2, 3])Array.prototype.concat.apply([ ], arr)其實可以寫成 [ ].concat(arr)
const arr = [1, 2, 4, [2, 4, 5, [1, 2, [4]]]];
function flatten(arr) {
????let res =Array.prototype.concat.apply([], arr)
????const flag = arr.some(item => iteminstanceof Array)//some( ) 返回一個Boolean值
????if (flag) {
????????return flatten(res)//如果i數(shù)組中還嵌套數(shù)組鼓拧,遞歸
}
????return arr;
}
console.log(flatten(arr));// [1, 2, 4, 2, 4, 5, 1, 2, 4]
20.數(shù)組去重
1.使用Set( )函數(shù):
function unique1(arr) {
????const set =new Set(arr);
? ? return [...set]//ES6結(jié)構(gòu)賦值
}
2.遍歷數(shù)組(性能上有所欠缺,需要多次遍歷越妈,indexOf本質(zhì)也是遍歷)
function unique2(arr) {
????const res = [];
? ? arr.forEach( item => {
????????if (res.indexOf(item) <0) {
????????res.push(item)
????????}
????})
????????return res;
}
21.數(shù)組排序(升序季俩,降序)
1.使用Array.prototype.sort( )方法。sort()排序規(guī)則是按照UTF-16編碼排序梅掠。sort( )中可以傳入函數(shù)作為參數(shù)酌住。
? ?升序:arr.sort((a, b) => a - b);降序:arr.sort((a, b) => b - a)阎抒;
2.冒泡算法酪我。冒泡算法就是將數(shù)組元素中相鄰的兩個元素的值大小做比較,交換順序且叁。
????for (let i =0; i < arr.length; i ++ ) {
????????for (let j =0; j < arr.length - 1 - i; i ++) {
????????????if (arr1[j] >arr1[j +1]) {
????????????????let temp =arr1[j];
? ? ? ? ? ? ????arr1[j] =arr1[j +1];
? ? ? ? ? ? ? ? arr1[j +1] = temp;
? ? ?????????? }
????????}
????}
22.手寫深拷貝
涉及到多層次的對象和數(shù)組就需要遞歸都哭。
function deepClone(obj) {
????let res;
? ? if (typeof obj ==="object" || obj ==null) { //判斷傳入?yún)?shù)的類型
????????return obj;
? ? }
????if (obj instanceof Array) { //是數(shù)組則賦值為數(shù)組
????res = [];
? ? }????else {
????????res = { } //否則賦值為對象
????}
????for (let keyin obj) {
????????if (obj.hasOwnProperty(key)) {//這個是為了代碼嚴(yán)謹(jǐn)。obj上可能會有原型的key逞带。不寫不太影響結(jié)果
????????????res[key] =deepClone(obj[key])质涛;//遞歸
????????}
}
????return res;
}
22.函數(shù)節(jié)流防抖
1.函數(shù)防抖:
function debounce(fn, delay) {
????let timer;
? ? return function () {
????????if (timer) {
????????????clearTimeout(timer);
? ? ? ? }
????timer =setTimeout(function () {
????????fn.apply(this, arguments)
????????})
????????timer =null;
? ? }
}
2.函數(shù)節(jié)流:
function throttle(fn, delay) {
? ? ?let timer =null;
? ? return function () {
????????if (timer) {
????????return;
? ? ? ? }
????timer =setTimeout(function () {
????????fn.apply(this, arguments)
????????}, delay);
? ? ? ? timer =null;
? ? }
}
23.Promise函數(shù)和異步
Promise是ES6中新增的函數(shù)。主要是解決callback hell(回調(diào)地獄)掰担。Promise((resolve,rejecte)=> {})三種狀態(tài):pending(將要進(jìn)行)怒炸、fulfilled(完成)带饱、rejecte(失敗)。同時還衍生了generator函數(shù)勺疼,async await(解決then()回調(diào)問題)教寂。Promise函數(shù)體是同步,then()方法是異步执庐。then( () => { } )接受成功的回調(diào)函數(shù)酪耕,catch(() => { })接受失敗后的回調(diào)。?
24.Cookie轨淌、session迂烁、Localstorage、Sessionstorage的區(qū)別和作用
Cookie中的數(shù)據(jù)存儲在客戶端递鹉,session中的數(shù)據(jù)存儲在服務(wù)器端盟步。所以從安全性上考慮,用戶的登陸信息需要存儲在session當(dāng)中躏结。cookie中僅保存一些非安全性的信息却盘,比如用戶登陸狀態(tài)過期的時間,如果不設(shè)置用戶登陸狀態(tài)過期時間媳拴,默認(rèn)頁面關(guān)閉黄橘,登陸狀態(tài)也就消失。
Localstorage是把數(shù)據(jù)存儲在瀏覽器本地的一種存儲方式屈溉。如果用戶不手動清除數(shù)據(jù)信息塞关,則數(shù)據(jù)不會消失。Sessionstorage則是僅保存當(dāng)前頁面的數(shù)據(jù)信息语婴。當(dāng)前頁面關(guān)閉描孟,則數(shù)據(jù)信息自動清除。
在存儲大小方面砰左。cookie的存儲容量為4kb左右匿醒,session為4mb。
25.地址欄輸url會發(fā)生什么缠导?
1.第一步是查看本地緩存
2.第二步是域名DNS解析
3.第三部是建立TCP鏈接
4.第四步是發(fā)起HTTP請求
5.瀏覽器接收到服務(wù)器返回的文件廉羔,渲染
26.TCP/IP模型
TCP/IP是一系列網(wǎng)絡(luò)協(xié)議的總稱。這些協(xié)議的目的是使得計算機(jī)之間可以進(jìn)行信息交換僻造。
TCP/IP模型四層架構(gòu)從上到下分別是鏈路層憋他、網(wǎng)絡(luò)層、傳輸層髓削、應(yīng)用層
1.鏈路層的作用是負(fù)責(zé)建立電路連接竹挡,是整個網(wǎng)絡(luò)的物理基礎(chǔ),典型的協(xié)議包括以太網(wǎng)立膛、ADSL等揪罕。
2.網(wǎng)絡(luò)層負(fù)責(zé)分配地址和傳送二進(jìn)制數(shù)據(jù)梯码,主要要協(xié)議是IP協(xié)議
3.傳輸層負(fù)責(zé)傳送文本數(shù)據(jù),主要協(xié)議是TCP
4.應(yīng)用層負(fù)責(zé)傳送各種最終形態(tài)的數(shù)據(jù)好啰,是直接與用戶信息打交道的層轩娶,主要寫是HTTP、ftp等