1.js當(dāng)中有哪些數(shù)據(jù)類型
5個(gè)基礎(chǔ):字符串酣藻,布爾笑窜,數(shù)值胀糜,null颅拦,undefined,1個(gè)復(fù)雜:Object
在es6下新增一種叫symbol的數(shù)據(jù)類型教藻,而且初始化不需要new操作符
防止屬性名的沖突,這對(duì)于一個(gè)對(duì)象由多個(gè)模塊構(gòu)成的情況非常有用,能防止某一個(gè)鍵被不小心改寫或覆蓋
1.2 如何對(duì)這些數(shù)據(jù)類型進(jìn)行判斷
- 1.對(duì)于普通的數(shù)據(jù)類型
typeof右锨,他的返回值有六種括堤,null和object返回都是object,而其余的都是對(duì)應(yīng)的字符串绍移,包括function悄窃。
1.2.1 typeof 通常會(huì)跟一個(gè)(),這個(gè)括號(hào)可不可以省略
typeof是一個(gè)一元運(yùn)算符,所以是可以不跟括號(hào)的蹂窖,括號(hào)的作用只是為了看起來方便轧抗,而且一元運(yùn)算符有很高的優(yōu)先級(jí),即使做多個(gè)typeof判斷也沒有問題
1.2.2 既然null和object返回都是object瞬测,那么如何對(duì)對(duì)象進(jìn)行數(shù)據(jù)類型判斷
1.數(shù)組數(shù)據(jù)類型判斷
+1.constructor
每一個(gè)對(duì)象實(shí)例都可以通過 constrcutor 對(duì)象訪問它的構(gòu)造函數(shù)
console.log([].constrcutor)
//f Array(){[native code]}
- 2.isArray()
Array.isArray([1, 2, 3]);
// true
3.特殊情況
一般情況上面兩種方法沒有問題横媚,當(dāng)頁(yè)面存在兩個(gè)iframe纠炮,而且判斷是在兩個(gè)iframe之間進(jìn)行判斷的時(shí)候,那么這兩種方法就很有可能出現(xiàn)問題灯蝴,因?yàn)閮蓚€(gè)頁(yè)面就會(huì)有兩個(gè)window對(duì)象恢口,而constrcutor 判斷出的構(gòu)造函數(shù)是在兩個(gè)不同的window對(duì)象上的,所以這個(gè)時(shí)候使用這兩個(gè)方法判斷的時(shí)候就會(huì)出現(xiàn)問題穷躁。4.判斷一個(gè)對(duì)象是否為數(shù)組的正確方法
Object.prototype.toString().call(變量) -->得到類型的字符串
2.數(shù)組有哪些方法
join()
push()和pop()
shift() 和 unshift()
sort()
reverse()
concat()
arrayObject.slice(start,end)
arrayObject.splice(index,howmany,item1,.....,itemX)
splice() 方法向/從數(shù)組中添加/刪除項(xiàng)目耕肩,然后返回被刪除的項(xiàng)目。
indexOf()和 lastIndexOf()
forEach()
map(func) :通過指定函數(shù)處理數(shù)組的每個(gè)元素问潭,并返回處理后的數(shù)組猿诸。
var numbers = [4, 9, 16, 25];
function myFunction() {
console.log(numbers.map(Math.sqrt));
}
輸出結(jié)果為:
2,3,4,5
filter():創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是通過檢查指定數(shù)組中符合條件的所有元素
every():用于檢測(cè)數(shù)組所有元素是否都符合指定條件(通過函數(shù)提供)
some(func) :用于檢測(cè)數(shù)組中的元素是否滿足指定條件(函數(shù)提供)
var ages = [3, 10, 18, 20];
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
console.log(ages.some(checkAdult));
}
reduce()和 reduceRight()
reduce()
方法接收一個(gè)回調(diào)函數(shù)作為累加器狡忙,數(shù)組中的每個(gè)值(從左到右)開始合并梳虽,最終為一個(gè)值。
function callbackfn(preValue,curValue,index,array){}
var arr = [0,1,2,3,4];
arr.reduce(function (preValue,curValue,index,array) {
return preValue + curValue;
}); // 10
可以使用reduce()
實(shí)現(xiàn)數(shù)組求和
2.1 對(duì)于這些數(shù)組的方法有哪些對(duì)原數(shù)組是有影響的去枷?
push()和pop()怖辆,shift() 和 unshift(),sort()删顶,reverse()竖螃,splice()
其它的不會(huì)影響,要么返回新數(shù)組要么返回其他數(shù)據(jù)類型逗余,數(shù)字或者布爾類型
2.2 數(shù)組如何去重
- 1.創(chuàng)建空數(shù)組特咆,使用循環(huán)push的方式,一個(gè)一個(gè)把元素push進(jìn)去录粱,push之前用indexof判斷一下push的值在新數(shù)組里有沒有腻格,沒有就push進(jìn)去,有就判斷下一個(gè)
- 2.直接在原先的數(shù)組上進(jìn)行去重啥繁,用splice方法菜职,在原數(shù)組上依次進(jìn)行對(duì)比,如果對(duì)比的元素在他前面或者后面存在的話旗闽,就把當(dāng)前這個(gè)值刪掉酬核,并且數(shù)組長(zhǎng)度減一
var arr = [1,3,4,5,6,5,6,6,6,4];
for(var i = 0 ; i < arr.length ; i++){
for(var j = i+1 ; j < arr.length ; j++){
if(arr[i] == arr[j]){
arr.splice(j,1);
j--;
}
}
}
- 3.利用對(duì)象的屬性不能重復(fù)的特性進(jìn)行去重
Array.prototype.distinct = function (){
var arr = this,
i,
obj = {},
result = [],
len = arr.length;
for(i = 0; i< arr.length; i++){
if(!obj[arr[i]]){ //如果能查找到,證明數(shù)組元素重復(fù)了
obj[arr[i]] = 1;
result.push(arr[i]);
}
}
return result;
};
var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];
var b = a.distinct();
console.log(b.toString()); //1,2,3,4,5,6,56
遍歷 數(shù)組的元素适室,將元素作為對(duì)象的屬性并賦值嫡意,每一次遍歷的時(shí)候判斷對(duì)象是否有該屬性,如果沒有再給對(duì)象添加屬性
- 4.先對(duì)原數(shù)組進(jìn)行排序捣辆,然后循環(huán)蔬螟,如果相鄰的兩個(gè)元素相同,那就刪掉一個(gè)元素
- 5.一行代碼實(shí)現(xiàn)數(shù)組去重
//ES6中新增了Set數(shù)據(jù)結(jié)構(gòu)汽畴,類似于數(shù)組旧巾,但是 它的成員都是唯一的 耸序,其構(gòu)造函數(shù)可以接受一個(gè)數(shù)組作為參數(shù),如:
let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];
let set = new Set(array);
arr=[...new_set];)
console.log(arr);
// =>[1, 2, 3, 4, 5]
2.3 偽數(shù)組有哪些菠齿?如何把一個(gè)偽數(shù)組轉(zhuǎn)化為真數(shù)組
2.3.1 偽數(shù)組有哪些佑吝?
- 1.dom選擇器選出來的節(jié)點(diǎn)列表
- 2.函數(shù)中的arguments是對(duì)象,函數(shù)參數(shù)不確定的時(shí)候通常會(huì)調(diào)用arguments對(duì)象
- 3.jquery選擇器選出的也是偽數(shù)組绳匀,實(shí)際上他也是一個(gè)jquery對(duì)象
2.3.2 如何把一個(gè)偽數(shù)組轉(zhuǎn)化為真數(shù)組
- 1.創(chuàng)建數(shù)組芋忿,然后把偽數(shù)組里的值依次push進(jìn)去
- 2.Array.prototype.slice().call(偽數(shù)組)或者[].prototype.slice().call
3.字符串
3.1 字符串有哪些方法
- 1.str.charAt(index); 返回子字符串,index為字符串下標(biāo)疾棵,index取值范圍[0,str.length-1]
- 2.str.charCodeAt(index); 返回子字符串的unicode編碼戈钢,index取值范圍同上
- 3.String.fromCharCode(num1,num2,...,numN); 根據(jù)unicode編碼返回字符串
- 4.indexOf(),lastIndexOf()
- 5.slice(),replace()
- 6.match(): 返回所有查找的關(guān)鍵字內(nèi)容的數(shù)組
- 7.split()
- 8.substring()(不接受負(fù)值參數(shù)),substr()
- 9.toLowerCase(),toUpperCase()
- 10.str.concat("thank you")); //連接字符串
- 11.str.trim()
3.2 slice,substring()是尔,substr()有什么區(qū)別
- 1.相同點(diǎn):
這三個(gè)方法都是返回被操作字符串的一個(gè)子字符串殉了,
就是返回一個(gè)新的字符串。
1拟枚、第一個(gè)參數(shù)是指定字符串的開始位置
2薪铜、第二次參數(shù)(在指定的情況下)表示字符串到哪里結(jié)束
3、如果沒有第二個(gè)參數(shù)恩溅,則將字符串結(jié)束的未位作為結(jié)束位置 - 2.不同點(diǎn):
1隔箍、slice()和substring()第二次參數(shù)指定的是字符串最后一個(gè)字符后面的位置;
substr()第二個(gè)參數(shù)指定返回的字符串個(gè)數(shù)脚乡;
2蜒滩、slice() 會(huì)將所有的負(fù)數(shù)與字符串的長(zhǎng)度相加
substr() 會(huì)將第一個(gè)負(fù)參數(shù)與字符串長(zhǎng)度相加,第二個(gè)負(fù)參數(shù)轉(zhuǎn)化為 0
substring() 將所有的負(fù)參數(shù)轉(zhuǎn)化為 0
4.數(shù)值類型
4.1 如何判斷是不是NaN
isNaN()函數(shù)奶稠,它是判斷一個(gè)值能否被 Number() 合法地轉(zhuǎn)化成數(shù)字俯艰。
但是對(duì)于一些沒法轉(zhuǎn)化成數(shù)字的值,它都有可能告訴你這是數(shù)值锌订。
所以最好的辦法是全等和自身進(jìn)行判斷竹握,因?yàn)樵趈s當(dāng)中,只有NaN不全等自身
或者es6的Object.is和===一樣
5.布爾類型
5.1 在js當(dāng)中那些值會(huì)轉(zhuǎn)化成布爾類型為false
六種:undefined辆飘,null涩搓,0/-0,NaN劈猪,false,‘’
5.2 如何快速的將一個(gè)值轉(zhuǎn)為布爾類型
!!+值
5.3 new Boolean(false)->true
5.3.1.new操作符的執(zhí)行過程
+1.創(chuàng)建一個(gè)空對(duì)象
- 2.修改this指針良拼,將this指針指向創(chuàng)建出來的這個(gè)對(duì)象
- 3.運(yùn)行構(gòu)造函數(shù)里面的所有代碼
- 4.將創(chuàng)建出來的對(duì)象作為返回值進(jìn)行返回
使用new操作符的時(shí)候如果沒有參數(shù)的時(shí)候战得,括號(hào)可以省略
5.3.2 對(duì)于構(gòu)造函數(shù)來講,里面的返回值應(yīng)該是什么樣的
返回值分成這樣幾個(gè)問題:
- 1.new操作符本來就會(huì)返回一個(gè)對(duì)象然后再將它返回
- 2.如果在構(gòu)造函數(shù)里寫了一個(gè)返回值
- 1.如果返回的不是一個(gè)對(duì)象庸推,會(huì)被忽略
- 2.返回的是一個(gè)對(duì)象常侦,會(huì)把設(shè)置的對(duì)象進(jìn)行返回(單例模式)
6.js當(dāng)中繼承是如何實(shí)現(xiàn)的
對(duì)象a浇冰,對(duì)象b,讓b繼承于a
1.原型鏈繼承:
子類的原型對(duì)象指向父類的實(shí)例
- 1.優(yōu)點(diǎn)
1簡(jiǎn)單:B.prototype=new A
2父類原型原型對(duì)象中增加的屬性和方法在子類中都能訪問的到 - 2.缺點(diǎn)
1為子類增加方法聋亡,必須在B.prototype=new A之后
2屬性和方法都是共享的肘习。
3無法實(shí)現(xiàn)多繼承。
4無法傳參坡倔。
2.構(gòu)造函數(shù)式繼承
原型鏈繼承雖然簡(jiǎn)單漂佩,但是無法傳參是最大弱點(diǎn)(多繼承在開發(fā)中使用并不多)。如果想讓子類擁有父類的方法和屬性罪塔,最簡(jiǎn)單的方式就是將父類的構(gòu)造函數(shù)拷貝到子類中一份投蝉。或者說在子類的構(gòu)造函數(shù)中運(yùn)行一下父類的構(gòu)造函數(shù)征堪。
1.核心
用call和apply在子類的構(gòu)造函數(shù)中運(yùn)行父類的構(gòu)造函數(shù)瘩缆,一般使用A.apply(this,arguments)、2.優(yōu)點(diǎn)
1可以實(shí)現(xiàn)多繼承(call或apply多個(gè)父類)
2解決的共享問題
3可以傳參佃蚜。3.缺點(diǎn)
1實(shí)例只是子類的實(shí)例庸娱,不是父類的實(shí)例。無法被instanceof和isPropertyOf識(shí)別谐算。
2只能繼承構(gòu)造函數(shù)內(nèi)的屬性和方法熟尉,不能繼承原型對(duì)象上的屬性和方法。
3方法都是在構(gòu)造函數(shù)中運(yùn)行的氯夷,無法復(fù)用臣樱。
instanceof的用法
- 1.instanceof 就是判斷一個(gè)實(shí)例是否屬于某種類型
// 判斷 foo 是否是 Foo 類的實(shí)例
function Foo(){}
var foo = new Foo();
console.log(foo instanceof Foo)//true
- 2.instanceof 可以在繼承關(guān)系中用來判斷一個(gè)實(shí)例是否屬于它的父類型
// 判斷 foo 是否是 Foo 類的實(shí)例 , 并且是否是其父類型的實(shí)例
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型繼承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true
isPrototypeOf的用法
isPrototypeOf()方法測(cè)試一個(gè)對(duì)象是否存在另一個(gè)對(duì)象的原型鏈上
var o={};
function Person(){};
var p1 =new Person();//繼承自原來的原型,但是現(xiàn)在已經(jīng)無法訪問
Person.prototype=o;
var p2 =new Person();//繼承自o
console.log(o.isPrototypeOf(p1));//false o是不是p1的原型
console.log(o.isPrototypeof(p2));//true o是不是p2的原型
3.組合式繼承
同時(shí)使用原型繼承和借用構(gòu)造函數(shù)繼承兩種方式腮考。在子類的構(gòu)造函數(shù)內(nèi)使用call或apply調(diào)用父類雇毫,并且子類的prototype指向某一個(gè)父類的實(shí)例。
1.優(yōu)點(diǎn)
結(jié)合了原型繼承和借用構(gòu)造函數(shù)繼承兩種方式的優(yōu)點(diǎn)踩蔚,可以傳參棚放,可以多繼承,可以使用父類構(gòu)造函數(shù)的方法和屬性馅闽,也可以使用父類原型對(duì)象上的方法和屬性飘蚯。同時(shí)也可以被instanceof和isPropertyOf識(shí)別2.缺點(diǎn)
1父類被調(diào)用了兩次,第一次是在使用call或apply的時(shí)候福也,第二次是在將子類的原型對(duì)象指向父類的實(shí)例的時(shí)候局骤。(效率降低)
2父類構(gòu)造函數(shù)內(nèi)所設(shè)置的屬性或方法在子類的實(shí)例和原型對(duì)象中(上圖中的紅色部分)個(gè)存在了一份,由于同名覆蓋的原因暴凑,使用時(shí)并不受影響峦甩。但是會(huì)占用額外的內(nèi)存空間。(浪費(fèi)空間)
4.原型式繼承(記住上面三個(gè))
創(chuàng)建一個(gè)構(gòu)造函數(shù)B
B.prototype = a;
創(chuàng)建b實(shí)例對(duì)象時(shí)
b = new B 這樣b對(duì)象就繼承了a
直接讓一個(gè)對(duì)象繼承于另一個(gè)對(duì)象
5.寄生式繼承现喳?凯傲??
將原型式繼承用函數(shù)封裝起來
6.組合寄生式繼承(完美繼承)
先通過原型鏈繼承創(chuàng)建一個(gè)對(duì)象犬辰,比如說這個(gè)對(duì)象叫object,object繼承于a冰单,讓object的constructor指向b幌缝,然后讓b的prototype指向剛剛創(chuàng)建的對(duì)象object
這些繼承方式的優(yōu)缺點(diǎn)和應(yīng)用場(chǎng)景
- 4.原型式繼承,寄生式繼承
不是實(shí)現(xiàn)兩個(gè)構(gòu)造函數(shù)的繼承而是實(shí)現(xiàn)兩個(gè)對(duì)象的繼承诫欠, - 5.組合寄生式繼承(完美繼承)
很完美就是寫起來麻煩
6.1 什么是繼承
繼承是指一個(gè)對(duì)象(子類)直接使用另一對(duì)象(父類)的屬性和方法涵卵。在子類中也可以重寫父類的方法,覆蓋父類中同名的方法呕诉。繼承的優(yōu)點(diǎn)是提高了代碼的效率缘厢,避免了代碼重寫。
6.2 談一談你對(duì)原型鏈的理解
我認(rèn)為原型鏈?zhǔn)且环N關(guān)系,一種實(shí)例對(duì)象和原型對(duì)象之間的關(guān)系,這個(gè)關(guān)系是通過原型(proto)來聯(lián)系的甩挫。
6.3 談?wù)剺?gòu)造函數(shù)贴硫,原型對(duì)象和實(shí)例對(duì)象之間的關(guān)系
+1.構(gòu)造函數(shù)的原型屬性prototype指向了(該構(gòu)造函數(shù)的)原型對(duì)象,在原型對(duì)象里有共有的方法伊者,所有構(gòu)造函數(shù)聲明的實(shí)例都可以共享這個(gè)方法英遭。
- 2.原型對(duì)象Foo.prototype
Foo.prototype保存著實(shí)例共享的方法,有一個(gè)指針constructor指回構(gòu)造函數(shù)亦渗。 - 3.實(shí)例
假設(shè)f1和f2是Foo這個(gè)對(duì)象的兩個(gè)實(shí)例挖诸,這兩個(gè)對(duì)象也有屬性proto,指向構(gòu)造函數(shù)的原型對(duì)象法精,可以訪問原型對(duì)象的所有方法多律。 - 4.構(gòu)造函數(shù)可以實(shí)例化對(duì)象
- 5.構(gòu)造函數(shù)Foo也是對(duì)象,它的proto屬性指向Function.prototype
- 6.Function.prototype也是對(duì)象搂蜓,他的proto屬性指向Object.prototype狼荞,最后Object.prototype的proto屬性指向null
總結(jié):由對(duì)象實(shí)例起步,由proto屬性不斷向上指向?qū)?yīng)構(gòu)造函數(shù)的原型對(duì)象帮碰,直至Object.prototype的proto屬性指向null相味,形成原型鏈
7.script標(biāo)簽上的async和defer屬性的區(qū)別
- 1.defer是延遲執(zhí)行,它會(huì)同時(shí)并行地去加載多個(gè)js殉挽,然后按照順序從上到下執(zhí)行
- 2.async是異步加載丰涉,它和defer一樣會(huì)并行地去加載多個(gè)js,但是它是下載完之后就立刻執(zhí)行斯碌,并不是按書寫順序去執(zhí)行
面試怎么答 - 1.在js中javascript代碼的加載和執(zhí)行會(huì)阻塞頁(yè)面的html渲染
- 2.正常的js文件的下載都是同步的依次去下載一死,但是寫了async和defer,都會(huì)以
異步的方式去加載外部的js文件 - 3.async是在外部js加載完之后傻唾,如果瀏覽器空閑摘符,并且load事件觸發(fā)的時(shí)候,會(huì)在load事件觸發(fā)之前去執(zhí)行
- 4.defer是在js加載完成之后,等到整個(gè)文檔解析完成之后逛裤,才會(huì)去執(zhí)行。他們倆個(gè)的執(zhí)行時(shí)間是不一樣的猴抹。如果對(duì)一個(gè)script標(biāo)簽使用了defer屬性带族,即使把script標(biāo)簽放在head里面,執(zhí)行的效果也類似于你把它放在body后面蟀给,但是由于他是異步加載的蝙砌,可能會(huì)節(jié)省一些時(shí)間,但是他執(zhí)行的時(shí)間是沒辦法確定的跋理。具體的用法要根據(jù)項(xiàng)目的需求
8.promise
8.1 promise實(shí)現(xiàn)的方式
創(chuàng)建的時(shí)候择克,new Promise(resolve,reject),成功和失敗的回調(diào),
使用的時(shí)候調(diào)用then和catch
8.2 如果頁(yè)面上有多個(gè)promise前普,如何等到所有promise執(zhí)行完成之后再執(zhí)行后面的內(nèi)容
在promise中有一個(gè)特殊的方法all肚邢,還有一個(gè)race,他們有什么區(qū)別
使用方式上都一樣拭卿,區(qū)別是
1.all會(huì)把數(shù)組當(dāng)中所有promise執(zhí)行完之后骡湖,才會(huì)把所有的決議結(jié)果以數(shù)組的方式傳入到回調(diào)里面(是按順序執(zhí)行的)
2.而race,會(huì)把數(shù)組當(dāng)中第一個(gè)產(chǎn)生的決議值傳給回調(diào)
Promise.race([p1, p2, p3])里面哪個(gè)結(jié)果獲得的快峻厚,就返回那一個(gè)結(jié)果响蕴,不管結(jié)果本身是成功狀態(tài)還是失敗狀態(tài)。
8.3 promise中的then和catch的返回值是什么
返回新的promise對(duì)象惠桃,所以可做鏈?zhǔn)讲僮?/p>
8.4 如果在promise的then中顯式的返回一個(gè)非promise對(duì)象浦夷,這個(gè)時(shí)候如何執(zhí)行
返回值還是一個(gè)promise對(duì)象弛作,但是后面的then會(huì)立即執(zhí)行不會(huì)等前面的
8.5 在promise當(dāng)中異常捕獲是如何實(shí)現(xiàn)的伊约,這種異常捕獲和try/catch有什么優(yōu)勢(shì)
- 對(duì)于try/catch來講,嘗試后面的代碼能否運(yùn)行哄啄,一種異常的捕獲機(jī)制誓禁。
先調(diào)用try里面的方法懈息,如果里面報(bào)錯(cuò)了,再把錯(cuò)誤傳到catch里面進(jìn)行處理摹恰。
不能捕獲異步下的異常辫继,比如要發(fā)送一個(gè)ajax請(qǐng)求,只能在ajax的回調(diào)里使用俗慈,或者整體包裹一個(gè)try/catch
- 對(duì)于promise來講姑宽,它里面存在兩種狀態(tài),resolved和rejected闺阱,只要是發(fā)生了異撑诔担或者錯(cuò)誤,promise會(huì)進(jìn)入rejected決議,進(jìn)入catch里面進(jìn)行處理瘦穆。
9.es6新增了哪些東西纪隙,你在項(xiàng)目中用了哪些
9.1 import、export模塊化
export var a = 'jspang';//temp.js
//export default var a='jspang';
//import str from './temp';default可以在導(dǎo)入的時(shí)候自定義變量名
import {a} from './temp.js';//index.js
console.log(a);
9.2 解構(gòu)賦值
數(shù)組扛或,字符串绵咱,對(duì)象也可
letl [a,b,c]=[1,2,3];
9.3 let,const
9.4 class和extends
class Coder{
name(val){
console.log(val);
return val;
}
constructor(a,b){
this.a=a;
this.b=b;
}
add(){
return this.a+this.b;
}
}
let jspang=new Coder(1,2);
console.log(jspang.add());
class htmler extends Coder{//類的繼承
}
let pang=new htmler;
pang.name('技術(shù)胖');
9.5 內(nèi)置函數(shù)的拓展
1.函數(shù)的拓展
箭頭函數(shù)熙兔,傳參的默認(rèn)值悲伶,rest參數(shù)(...)
箭頭函數(shù)和普通函數(shù)區(qū)別
- 箭頭函數(shù)沒有prototype,所以箭頭函數(shù)本身沒有this
- 箭頭函數(shù)的this指向在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this
- 箭頭函數(shù)沒有arguments住涉,普通函數(shù)有
- 使用new調(diào)用箭頭函數(shù)會(huì)報(bào)錯(cuò)
- 不可以使用yield命令麸锉,因此箭頭函數(shù)不能用作 Generator 函數(shù)。
yield是ES6的新關(guān)鍵字舆声,使生成器函數(shù)執(zhí)行暫停
2.字符串的拓展
模板字符串
3.數(shù)組的拓展
from of數(shù)組的遍歷,拓展運(yùn)算符...
4.對(duì)象的拓展
- 1.屬性的簡(jiǎn)潔表達(dá)式(ES6中允許使用變量來作為屬性和方法花沉,書寫更簡(jiǎn)便)
對(duì)于函數(shù)返回值返回對(duì)象非常的方便 - 2.解構(gòu)賦值
新增變量或者import一些變量 - 3.is, keys,values,assign,entries
https://www.cnblogs.com/marvintang1001/p/11809665.html
is:嚴(yán)格相等 Object.is(+0, -0) // false
keys:返回一個(gè)數(shù)組纳寂,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名主穗。
values:返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值毙芜。
assign:用于對(duì)象的合并忽媒,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)腋粥。第一個(gè)參數(shù)是目標(biāo)對(duì)象晦雨,后面的參數(shù)都是源對(duì)象。注意隘冲,如果目標(biāo)對(duì)象與源對(duì)象有同名屬性闹瞧,或多個(gè)源對(duì)象有同名屬性,則后面的屬性會(huì)覆蓋前面的屬性展辞。
entries:方法返回一個(gè)數(shù)組奥邮,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對(duì)數(shù)組。只輸出屬性名非 Symbol 值的屬性罗珍。
5.class 類
6.promise對(duì)象
6.1 promise原理
https://juejin.im/post/5a0965c9f265da430e4ea8a0#heading-2
promise對(duì)象是一個(gè)構(gòu)造函數(shù)洽腺,通過new關(guān)鍵字來生成實(shí)例,promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject覆旱,他們是JavaScript引擎提供的兩個(gè)函數(shù)蘸朋。
resolve函數(shù)在異步操作由pending狀態(tài)(執(zhí)行進(jìn)行中)變?yōu)閞esolved(成功狀態(tài))時(shí)觸發(fā),傳遞操作成功后的結(jié)果扣唱;
reject函數(shù)在異步操作從pending狀態(tài)(執(zhí)行進(jìn)行中)變?yōu)閞ejected(失敗狀態(tài))時(shí)觸發(fā)藕坯,傳遞操作失敗后的結(jié)果团南。promsie狀態(tài)一旦修改就不能再變。
Promise.prototype上有一個(gè)then方法炼彪,處理狀態(tài)改變的代碼寫在then()方法里吐根,它的作用是為 Promise 實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù)。then方法的第一個(gè)參數(shù)是resolved狀態(tài)的回調(diào)函數(shù)霹购,第二個(gè)參數(shù)(可選)是rejected狀態(tài)的回調(diào)函數(shù)佑惠。
promise采用鏈?zhǔn)秸{(diào)用,then()為 Promise 注冊(cè)回調(diào)函數(shù)齐疙,參數(shù)為上一個(gè)任務(wù)的返回結(jié)果,所以鏈?zhǔn)秸{(diào)用里then 中的函數(shù)一定要 return 一個(gè)結(jié)果或者一個(gè)新的 Promise 對(duì)象旭咽,才可以讓之后的then 回調(diào)接收贞奋。
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的別名,也就是異步操作發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)穷绵,另外轿塔,then()方法里的回調(diào)函數(shù)發(fā)生錯(cuò)誤也會(huì)被catch()捕獲。
Promise.prototype.finally()
finally()方法是在ES2018引入標(biāo)準(zhǔn)的仲墨,該方法表示promise無論什么狀態(tài)勾缭,在執(zhí)行完then()或者catch()方法后,最后都會(huì)執(zhí)行finally()方法目养。
6.2 基本用法
const promise = new Promise((resolve, reject) => {
// 異步操作的代碼
if (success){
resolve(value);
} else {
reject(error);
}
});
6.3 簡(jiǎn)單實(shí)現(xiàn)一個(gè)promise
function myPromise(executor) {
let self=this;
self.status='pending';
self.value=undefined;
self.error=undefined;
function resolve(value) {
if(self.status==='pending'){
self.value=value
self.status="resolved"
}
}
function reject(reason) {
if(self.status==='pending'){
self.error=errot
self.status=status
}
}
try{
executor(resolve,reject)
}
catch (e) {
reject(e)
}
}
6.4 promise解決異步的思路
- 1.解決異步回調(diào)嵌套的問題俩由,比如說有多個(gè)ajax,他們之前的請(qǐng)求存在依賴關(guān)系癌蚁,也就是說幻梯,一個(gè)請(qǐng)求必須使用另一個(gè)請(qǐng)求返回的結(jié)果才能做這次請(qǐng)求,那么就需要將這個(gè)請(qǐng)求嵌套在另一個(gè)請(qǐng)求的回調(diào)函數(shù)里面才能獲取到另一個(gè)請(qǐng)求的返回結(jié)果努释。這樣的話如果有多個(gè)請(qǐng)求之間有相互依賴的關(guān)系碘梢,那就說他需要在多個(gè)ajax的回調(diào)函數(shù)里面嵌套ajax操作,這樣就形成了回調(diào)地獄伐蒂。這在團(tuán)隊(duì)合作中煞躬,這樣的項(xiàng)目對(duì)于后期的維護(hù)十分不利。
- 2.思路:將異步請(qǐng)求封裝成一個(gè)對(duì)象逸邦,將執(zhí)行成功與失敗分別作為這個(gè)對(duì)象的方法恩沛,執(zhí)行成功的時(shí)候?qū)⒔Y(jié)果放在這個(gè)對(duì)象的then方法中處理后續(xù)的邏輯,失敗了就調(diào)用這個(gè)對(duì)象的catch方法昭雌。這樣調(diào)用方法的執(zhí)行方式就能避免回調(diào)函數(shù)的嵌套复唤。如果有多個(gè)依賴的異步操作,promise還可以將多個(gè)對(duì)象的then方法變成鏈?zhǔn)讲僮髦蛭裕瑥亩苊饣卣{(diào)函數(shù)的嵌套佛纫。
- 3.promise的使用場(chǎng)景妓局,主要是用于保證多個(gè)異步請(qǐng)求都完成之后在進(jìn)行后續(xù)的業(yè)務(wù)
9.6 在項(xiàng)目當(dāng)中沒法直接使用es6,需要用babel進(jìn)行轉(zhuǎn)換為es5
要知道babel是如何轉(zhuǎn)換的呈宇,有能力自己將es6轉(zhuǎn)換為es5.尤其是let好爬,const的賦值,
箭頭函數(shù)甥啄,解構(gòu)和拓展運(yùn)算符存炮。
9.7 箭頭函數(shù)和以前普通的函數(shù)有什么區(qū)別
- 1.箭頭函數(shù)沒有arguments對(duì)象
- 2.this指向也發(fā)生了轉(zhuǎn)變
10.在js中事件是如何實(shí)現(xiàn)的
- 1.直接嵌入dom
在標(biāo)簽里直接加上click跟上函數(shù) - 2.直接綁定
先獲取到一個(gè)節(jié)點(diǎn),然后節(jié)點(diǎn).click= function,方便管理 - 3.事件監(jiān)聽
先獲取到一個(gè)節(jié)點(diǎn)蜈漓,addEventListener(解綁removeEventListener)穆桂,監(jiān)聽事件,并向指定元素添加該事件
問題:瀏覽器兼容性的處理融虽,對(duì)于ie來講綁定事件用的是attachEvent享完,解綁用detachEvent
10.1 事件委托
10.2 事件流
完整的事件流是從window開始然后再回到window這么一個(gè)過程
分成三個(gè)階段:1.捕獲階段 2.目標(biāo)階段 3.冒泡階段
偏的問題:
- 1.對(duì)于同一個(gè)dom元素,它既在三個(gè)階段都注冊(cè)了事件有额,當(dāng)這個(gè)事件被觸發(fā)的時(shí)候般又,整體的事件執(zhí)行順序是怎么樣的。
正常情況下事件是按照事件流的順序執(zhí)行巍佑。但是當(dāng)事件處于目標(biāo)階段茴迁,事件的執(zhí)行順序決定于綁定事件的書寫順序。 - 2.stopPrepagation和preventDefault有什么區(qū)別
一個(gè)是阻止默認(rèn)行為萤衰,一個(gè)阻止事件冒泡堕义。在ie下要處理兼容問題,要阻止默認(rèn)行為需要event.returnValue設(shè)置為 false腻菇,阻止事件冒泡胳螟,event.cancelBubble設(shè)置為true
10.3 target 和currentTarget的區(qū)別
target是事件的真正目標(biāo)
currentTarget是事件處理程序注冊(cè)的元素
11.網(wǎng)絡(luò)請(qǐng)求
11.1 http狀態(tài)碼
五類:
- 1開頭,信息響應(yīng)表示接收到了請(qǐng)求可以進(jìn)行后續(xù)的處理
- 2開頭筹吐,請(qǐng)求成功
- 3開頭糖耸,重定向響應(yīng),完成指定的響應(yīng)
- 4開頭丘薛,客戶端錯(cuò)誤
- 5開頭嘉竟,服務(wù)端錯(cuò)誤
常見狀態(tài)碼:301,303,400,500,502,503,504
11.2 輸入url敲回車,整個(gè)過程當(dāng)中發(fā)生了什么
- 1.輸入地址
- 2.瀏覽器查ip地址(dns解析洋侨,瀏覽器的系統(tǒng)緩存舍扰,路由緩存)
- 3.解析完成之后,瀏覽器向服務(wù)器發(fā)送一個(gè)http請(qǐng)求
- 4.發(fā)出去之后希坚,服務(wù)器會(huì)進(jìn)行一個(gè)重定向響應(yīng)边苹,比如你輸入一個(gè)地址jd.com,瀏覽器會(huì)把你重定向到www.jd.com, 接下去瀏覽器會(huì)跟蹤這個(gè)重定向響應(yīng)裁僧,然后取得這個(gè)地址个束,服務(wù)器接收到這個(gè)請(qǐng)求以后慕购,會(huì)對(duì)請(qǐng)求進(jìn)一步處理,然后服務(wù)器返回一個(gè)http的響應(yīng)茬底,響應(yīng)中包含了html的代碼
- 5.瀏覽器接收了html代碼以后沪悲,里面包含了很多東西,比如說圖片阱表,音頻殿如,js,css最爬。
瀏覽器會(huì)默認(rèn)按照它的一個(gè)渲染方式把整個(gè)頁(yè)面渲染出來涉馁,這里面涉及了異步請(qǐng)求的發(fā)送,js的解析和執(zhí)行
11.3 跨域
- 1.jsonp的跨域(JSON with padding(填充式JSON))
通過script標(biāo)簽實(shí)現(xiàn)爱致,
問題:1.只能get請(qǐng)求 2.存在安全隱患 - 2.cors 需要服務(wù)端進(jìn)行處理谨胞,如果前端需要帶cookie的話前后端都要處理
如果使用的是原生js的話,需要把xhr的withCredentials設(shè)置為true蒜鸡,如果用的是jq,要把jquey里面的xhrfileds的withCredentials設(shè)置為true - 3.服務(wù)端的nginx反向代理
使用:配置nginx的時(shí)候配置一個(gè)代理服務(wù)器牢裳,然后把它做成跳板逢防,比如說我要訪問domain2,但是前端只能訪問domain1蒲讯,nginx做一個(gè)跳板忘朝,每次訪問domain1的時(shí)候就自動(dòng)指向domain2這個(gè)接口。
原理是什么判帮?同源策略是瀏覽器的安全策略而不是http協(xié)議的一部分局嘁,如果在服務(wù)器端調(diào)用接口,因?yàn)椴淮嬖跒g覽器所以他走的只是http協(xié)議晦墙,所以不存在跨域的問題悦昵。
12.防抖節(jié)流
- 1.為什么要有函數(shù)節(jié)流和函數(shù)防抖
解決高頻觸發(fā)函數(shù)而帶來的負(fù)荷問題 - 2.什么是..
函數(shù)節(jié)流就是當(dāng)函數(shù)被高頻觸發(fā)時(shí),每間隔固定時(shí)間會(huì)觸發(fā)一次晌畅。簡(jiǎn)單理解為縮減函數(shù)執(zhí)行頻率但指,主要目的是稀釋函數(shù)執(zhí)行次數(shù)
函數(shù)防抖就是函數(shù)在固定的時(shí)間內(nèi)被觸發(fā)時(shí),不會(huì)立即執(zhí)行抗楔,而是每一次觸發(fā)都會(huì)重新計(jì)算時(shí)間棋凳。在達(dá)到固定時(shí)間后,僅僅執(zhí)行一次 - 3.從代碼層面說一下什么是...
函數(shù)節(jié)流连躏,通過閉包的方式標(biāo)記一個(gè)變量為true剩岳,在閉包內(nèi)返回的函數(shù)里進(jìn)行判斷,如果標(biāo)記為true入热,那么就執(zhí)行拍棕,并且把標(biāo)記改為false晓铆,如果標(biāo)記為false就直接return。在閉包返回的函數(shù)里面放一個(gè)settimeout莫湘,在settimeout里面執(zhí)行我們要執(zhí)行的函數(shù)尤蒿,并且把標(biāo)記變?yōu)閠rue。
const throttle = (fn, delay = 500) =>
{ let flag = true;
return (...args) => {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
},delay);
};
};
函數(shù)防抖幅垮,準(zhǔn)備一個(gè)變量來接受定時(shí)器的返回值腰池,把我們要執(zhí)行的函數(shù)放在一個(gè)settimeout里面,如果在固定時(shí)間內(nèi)再次觸發(fā)了函數(shù)忙芒,那么就把之前定時(shí)器關(guān)閉示弓,再執(zhí)行現(xiàn)在這個(gè)定時(shí)器。這樣一來呵萨,時(shí)間記錄會(huì)隨著函數(shù)的執(zhí)行重新進(jìn)行計(jì)算奏属,最后只會(huì)執(zhí)行一次
const debounce = (fn, delay) =>
{
let timer = null;
return (...args) =>
{ clearTimeout(timer);
timer = setTimeout(() =>
{ fn.apply(this, args); }, delay);
}; };
4.舉例
1.滾動(dòng)條滾動(dòng)到一定程度的時(shí)候會(huì)出現(xiàn)回到頂部按鈕,使用函數(shù)防抖潮峦,不需要隨著滾動(dòng)每次都去判斷瀏覽器向上卷曲的高度囱皿,而是在滾動(dòng)過程中不進(jìn)行判斷,當(dāng)滾動(dòng)停止的時(shí)候才進(jìn)行一次判斷忱嘹,決定頂部按鈕是否出現(xiàn)
2.輪播圖左右切換按鈕嘱腥,不停的快速點(diǎn)擊會(huì)造成鬼畜效果,可以使用函數(shù)節(jié)流拘悦,在一個(gè)圖片效果的滾動(dòng)時(shí)間內(nèi)只觸發(fā)一次滾動(dòng)齿兔,只有當(dāng)這張圖片滾動(dòng)完畢以后,再次點(diǎn)擊切換按鈕的時(shí)候础米,才能觸發(fā)下一次圖片的滾動(dòng)
5.應(yīng)用場(chǎng)景
函數(shù)防抖--延時(shí)執(zhí)行
兩個(gè)條件:
1,如果客戶連續(xù)的操作會(huì)導(dǎo)致頻繁的事件回調(diào)(可能引起頁(yè)面卡頓).
2,客戶只關(guān)心"最后一次"操作(也可以理解為停止連續(xù)操作后)所返回的結(jié)果.
例如:
輸入搜索聯(lián)想分苇,用戶在不斷輸入值時(shí),用防抖來節(jié)約請(qǐng)求資源屁桑。
按鈕點(diǎn)擊:收藏,點(diǎn)贊,心標(biāo)等
函數(shù)節(jié)流:
防抖是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行医寿,節(jié)流是將多次執(zhí)行變?yōu)樵谝?guī)定時(shí)間內(nèi)只執(zhí)行一次.一般不會(huì)重置定時(shí)器.
兩個(gè)條件:
1,用戶連續(xù)頻繁地觸發(fā)事件
2,用戶不再只關(guān)心"最后一次"操作后的結(jié)果反饋.而是在操作過程中持續(xù)的反饋.
例如:
鼠標(biāo)不斷點(diǎn)擊觸發(fā),點(diǎn)擊事件在規(guī)定時(shí)間內(nèi)只觸發(fā)一次(單位時(shí)間內(nèi)只觸發(fā)一次)
監(jiān)聽滾動(dòng)事件掏颊,比如是否滑到底部自動(dòng)加載更多糟红,用throttle來判斷
13.深淺拷貝
淺拷貝:
concat()
Object.assign()
-
slice()
var arr1 = [1,2,3,4]; var arr2 = [].concat(arr1) var arr3 = arr1.slice(0) var arr4 = [] arr4 = Object.assign(arr4,arr1))
拷貝之后數(shù)組各個(gè)值的指針還是指向相同的存儲(chǔ)地址
手寫
function shallowCopy(obj){
if(typeof obj!=='function'&& obj!==null){
let cloneObj=Array.isArray(obj)?[]:{}
for(let prop in obj){
cloneObj[prop]=obj[prop]
}
return cloneObj
}
else{
return obj
}
}
深拷貝:
JSON.stringfy(JSON.parse(obj))
1.時(shí)間對(duì)象=>字符串的形式
2.RegExp、Error => {}
3.function,undefined 丟失
4.NaN乌叶、Infinity和-Infinity會(huì)變成null
5.如果json里有對(duì)象是由構(gòu)造函數(shù)生成的盆偿,則序列化的結(jié)果會(huì)丟棄對(duì)象的 constructor
6.循環(huán)引用的情況也無法實(shí)現(xiàn)深拷貝
手寫深拷貝
基本上,如果你要往對(duì)象上添加數(shù)據(jù)准浴,又不想干擾垃圾回收機(jī)制事扭,就可以使用 WeakMap。
map數(shù)據(jù)類型:它類似于對(duì)象乐横,也是鍵值對(duì)的集合求橄,但是“鍵”的范圍不限于字符串今野,各種類型的值(包括對(duì)象)都可以當(dāng)作鍵。
const m = new Map()
m.set('name', 'lily')m.get('name') // "lily"
m.has('name') // true
m.delete('name')//true
var deepClone=(obj,map=new WeakMap())=>{
if(map.get(obj)){
return obj
}
let newObj;
if(typeof obj==='object'&& obj!==null){
newObj=Array.isArray(obj)?[]:{};
for(let prop in obj){
if(obj.hasOwnProperty(prop)){
newObj[prop]=deepClone(obj[prop])
}
}
return newObj;
}
else {
return obj;
}
};
14.this
this綁定函數(shù)的執(zhí)行上下文罐农,誰(shuí)調(diào)用它条霜,它就指向誰(shuí)。
分為默認(rèn)綁定涵亏、顯式綁定宰睡、隱式綁定、apply/call/bind綁定气筋、new綁定和箭頭函數(shù)綁定
默認(rèn)綁定:嚴(yán)格模式下this指向undefined拆内,非嚴(yán)格模式this指向window
14.1 call、apply宠默、bind
call麸恍、apply、bind都可以改變this的指向搀矫,但是apply接收參數(shù)數(shù)組抹沪,call接收的是參數(shù)列表 bind接收的是參數(shù)列表,但是apply和call調(diào)用就執(zhí)行瓤球,bind需要手動(dòng)執(zhí)行
箭頭函數(shù)綁定:箭頭函數(shù)的this是父作用域的this采够,不是調(diào)用時(shí)的this,其他方法的this是動(dòng)態(tài)的,而箭頭函數(shù)的this是靜態(tài)的
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| 正確地指向person 對(duì)象
}, 1000);
}
-------------------------
function Person() {
var self = this;
this.age = 0;
setInterval(function growUp() {
// 回調(diào)引用的是`that`變量, 其值是預(yù)期的對(duì)象.
self.age++;
}, 1000);
}
優(yōu)先級(jí):箭頭函數(shù)>new綁定>顯示綁定/apply/bind/call>隱式綁定>默認(rèn)綁定
14.2 箭頭函數(shù)和普通函數(shù)區(qū)別
- 箭頭函數(shù)沒有prototype冰垄,所以箭頭函數(shù)本身沒有this
- 箭頭函數(shù)的this指向在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this
- 箭頭函數(shù)沒有arguments,普通函數(shù)有
- 使用new調(diào)用箭頭函數(shù)會(huì)報(bào)錯(cuò)
- 不可以使用yield命令权她,因此箭頭函數(shù)不能用作 Generator 函數(shù)虹茶。
15.瀏覽器事件循環(huán)
- 1.同步任務(wù)在主線程執(zhí)行,在主線程外還有個(gè)任務(wù)隊(duì)列用于存放異步任務(wù)
- 2.主線程的同步任務(wù)執(zhí)行完畢隅要,異步任務(wù)入棧蝴罪,進(jìn)入主線程執(zhí)行
- 3.上述的兩個(gè)步驟循環(huán),形成eventloop事件循環(huán) 瀏覽器的事件循環(huán)又跟宏任務(wù)和微任務(wù)有關(guān)步清,兩者都屬于異步任務(wù)要门。
js異步有一個(gè)機(jī)制,就是遇到宏任務(wù)廓啊,先執(zhí)行宏任務(wù)欢搜,將宏任務(wù)放入任務(wù)隊(duì)列,再執(zhí)行微任務(wù)谴轮,將微任務(wù)放入任務(wù)隊(duì)列炒瘟,他倆進(jìn)入的不是同一個(gè)任務(wù)隊(duì)列。往外讀取的時(shí)候先從微任務(wù)里拿這個(gè)回調(diào)函數(shù)第步,然后再?gòu)暮耆蝿?wù)的任務(wù)隊(duì)列上拿宏任務(wù)的回調(diào)函數(shù)
宏任務(wù):
script
定時(shí)器 setTimeout setInterval setImmediate
微任務(wù):
promise
process.nextTick()
MutationObserver
16.document.ready和window.onload區(qū)別
document.ready是dom樹加載后執(zhí)行疮装,而window.onload是整個(gè)頁(yè)面資源加載完后執(zhí)行缘琅,所以document.ready比window.onload先執(zhí)行
17.什么是閉包,應(yīng)用場(chǎng)景是什么廓推?
- 1.可以保留局部變量不被釋放的代碼塊被稱作閉包
- 2.怎么形成:1.在外層函數(shù)中返回一個(gè)內(nèi)層函數(shù) 2.在內(nèi)存函數(shù)中能訪問到外層函數(shù)中的變量 3.一定要定義一個(gè)變量接受內(nèi)存函數(shù)
- 3.使用 :定義一些有作用域局限的持久化變量刷袍,這些變量可以作為緩存或者計(jì)算的中間量
- 4.弊端:持久化變量不會(huì)被正常釋放,會(huì)持續(xù)占用內(nèi)存空間樊展,很容易造成內(nèi)存的浪費(fèi)呻纹,一般需要額外手動(dòng)去清理。
- 5.應(yīng)用場(chǎng)景:封裝變量滚局,實(shí)現(xiàn)對(duì)數(shù)據(jù)的保護(hù)居暖。
實(shí)現(xiàn)設(shè)計(jì)模式:?jiǎn)卫J剑呗阅J教僦^察者模式等
實(shí)現(xiàn)封裝獨(dú)立的作用域:輪播圖的小圓點(diǎn)添加點(diǎn)擊事件太闺,解決循環(huán)變量i不正確的問題,防抖節(jié)流函數(shù)
18.localStorage嘁圈、sessionStorage省骂、cookie、session幾種web數(shù)據(jù)存儲(chǔ)方式對(duì)比
18.1 cookie 和 session
1.相同點(diǎn)
cookie 和 session 都是普遍用來跟蹤瀏覽用戶身份的會(huì)話方式最住。
2.區(qū)別
1.存放位置:cookie 數(shù)據(jù)存放在客戶端钞澳,session 數(shù)據(jù)放在服務(wù)器端,session 主要是服務(wù)端用來處理數(shù)據(jù)的涨缚。
2.安全性:cookie 本身并不安全轧粟,考慮到安全應(yīng)當(dāng)使用 session。
3.服務(wù)器性能:session 會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上脓魏。如果訪問量比較大兰吟,會(huì)比較消耗服務(wù)器的性能∶瑁考慮到減輕服務(wù)器性能方面的開銷混蔼,應(yīng)當(dāng)使用 cookie 。
4.數(shù)據(jù)大小限制:?jiǎn)蝹€(gè) cookie 保存的數(shù)據(jù)不能超過 4K珊燎,很多瀏覽器都限制一個(gè)域名最多保存 50 個(gè) cookie惭嚣。 將登陸信息等重要信息存放為 session、其他信息如果需要保留悔政,可以放在 cookie 中晚吞。
3.cookie 的使用
cookie 可通過 document.cookie
獲取全部 cookie。它是一段字符串谋国,是鍵值對(duì)的形式载矿。操作起來有些麻煩,可引入封裝好的庫(kù)進(jìn)行使用,比如 js-cookie
Cookies.set("name", "value", { expires: 7 }); // 設(shè)置一個(gè)cookie闷盔,7天后失效
Cookies.get("name"); // => 'value'
Cookies.remove("name");
18.2 localStorage 和 sessionStorage
在 web 本地存儲(chǔ)場(chǎng)景上弯洗,cookie 的使用受到種種限制,最關(guān)鍵的就是存儲(chǔ)容量太小和數(shù)據(jù)無法持久化存儲(chǔ)逢勾。
在 HTML 5 的標(biāo)準(zhǔn)下牡整,出現(xiàn)了 localStorage 和 sessionStorage 供我們使用。
-
1.cookie溺拱、localStorage 以及 sessionStorage 的異同點(diǎn)
分類 生命周期 存儲(chǔ)容量 存儲(chǔ)位置 cookie 默認(rèn)保存在內(nèi)存中逃贝,隨瀏覽器關(guān)閉失效(如果設(shè)置過期時(shí)間,在到過期時(shí)間后失效) 4KB 保存在客戶端迫摔,每次請(qǐng)求時(shí)都會(huì)帶上 localStorage 理論上永久有效的沐扳,除非主動(dòng)清除。 4.98MB(不同瀏覽器情況不同句占,safari 2.49M) 保存在客戶端沪摄,不與服務(wù)端交互。節(jié)省網(wǎng)絡(luò)流量 sessionStorage 僅在當(dāng)前網(wǎng)頁(yè)會(huì)話下有效纱烘,關(guān)閉頁(yè)面或?yàn)g覽器后會(huì)被清除 4.98MB(部分瀏覽器沒有限制) 同上 應(yīng)用場(chǎng)景:localStorage 適合持久化緩存數(shù)據(jù)杨拐,比如頁(yè)面的默認(rèn)偏好配置等;sessionStorage 適合一次性臨時(shí)數(shù)據(jù)保存擂啥。
-
使用方法
localStorage.setItem("name", "value"); localStorage.getItem("name"); // => 'value' localStorage.removeItem("name"); localStorage.clear(); // 刪除所有數(shù)據(jù) sessionStorage.setItem("name", "value"); sessionStorage.setItem("name"); sessionStorage.setItem("name"); sessionStorage.clear();
19.js中數(shù)組對(duì)象自定義排序
var data = [{ name: "zachary", age: 28 }, { name: "nicholas", age: 29 }];
function fun(name) {
return function (o1, o2) {
var value1 = o1[name];
var value2 = o2[name];
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
};
}
data.sort(fun("age"));
console.log(data)
定義一個(gè)函數(shù)哄陶,參數(shù)為排序的屬性名,這個(gè)函數(shù)返回一個(gè)比較函數(shù)哺壶,參數(shù)是兩個(gè)對(duì)象屋吨,在比較函數(shù)中對(duì)兩個(gè)對(duì)象的某一個(gè)屬性值進(jìn)行比較。使用函數(shù)的時(shí)候山宾,把它放在sort方法里离赫。