問題類型匯總
- ES6:全看
- CSS3:新特性、div盒子居中、清除浮動、動畫、canvas、畫三角形、定位的種類和區(qū)別
- Html:html5新特性、彈性盒子(怪異盒子)、
- Js:各種數(shù)據(jù)類型的處理方法、原型鏈、閉包、淺拷貝、深拷貝
- react:hooks、生命周期、組件之間的通信、高階組件
- 打包工具:webpack
- 其他:https協(xié)議、webStorage(localStorage和SessionStorage)和Cookie、跨域
具體問題:
ES6
var、let、const區(qū)別?
var定義的變量,沒有塊的概念,可以跨塊訪問,不能跨函數(shù)訪問;let和const都只能猜塊級作用域訪問,不能跨塊或者函數(shù)訪問。const聲明時(shí)必需賦值,且不能修改(不賦值,你后面又不能修改,那不是廢了)
var存在變量提升
const保證的是變量名指向的地址不變,而不是內(nèi)容不變,所以const聲明的數(shù)組,也是可能會被篡改的
使用箭頭函數(shù)應(yīng)該注意什么?
- this指向會變成指向父級
- 不能使用
arguments對象,不能用作構(gòu)造函數(shù),不能使用yield命令=>不能作為generator
函數(shù)
forEach、for in、for of三者的區(qū)別?
for in 遍歷出來的是key(對象和數(shù)組都能遍歷),
for of 便利出來的是value(for of只能遍歷數(shù)組,不能遍歷對象)
(Symbol作為屬性名,循環(huán)時(shí)是拿不到的)
rest參數(shù)需要注意的地方
- 只能作為函數(shù)的最后一個(gè)參數(shù)
- 函數(shù)的length屬性,不包括rest參數(shù)
Object.is()、==、===的區(qū)別
| == | === | Object.is() | |
|---|---|---|---|
| +0、-0 | true | true | false |
| NaN,Nan | false | false | true |
| undefined,undefined | true | true | true |
| null,null | true | true | true |
| null,undefined | true | false | false |
| null,NaN | false | false | false |
| undefined,NaN | false | false | false |
===在==的基礎(chǔ)上,認(rèn)為null和undefined是不相等的,Object.is()在===的基礎(chǔ)上,認(rèn)為+0和-0不相等,但是Nan和Nan想等
JS處理異步函數(shù)的方法
回調(diào)、事件發(fā)布與訂閱、Promise、Generator函數(shù)、async/await
如何監(jiān)聽數(shù)組被寫入或者讀取?
使用Proxy
ES6新增的特性
- let、const。
var有變量提升、可以跨塊訪問,不能跨函數(shù)訪問。let、const沒有變量提升,必須先聲明再使用,不能跨塊訪問,也不能跨函數(shù)訪問 - 箭頭函數(shù)
箭頭函數(shù)無需關(guān)鍵字function創(chuàng)建,更簡潔;箭頭函數(shù)沒有自己的this、arguments、不能用作構(gòu)造函數(shù)、不能用作generator函數(shù) - 模板字符串
用反引號包裹,再基礎(chǔ)字符串的基礎(chǔ)上,可以定義多行字符串,可以使用${}進(jìn)行字符串的拼接 - 解構(gòu)賦值
按照一定的語法可以從數(shù)組、字符串和對象中取值,然后賦值給變量。對于數(shù)組來說,相同位置的值會賦給相同位置的變量。對于對象來說相同鍵名的值會賦給同名變量。都支持賦默認(rèn)值
https://www.runoob.com/w3cnote/deconstruction-assignment.html - for of與for in
可以循環(huán)數(shù)組、set、map、對象、字符串。for of循環(huán)出來的是key,for in循環(huán)出來的是value - export和import
只是將代碼模塊化,分成不同文件。然后通過export和import的方式在其他地方使用 - Set數(shù)據(jù)結(jié)構(gòu)
Set是集合,一如它的數(shù)學(xué)定義,它內(nèi)部是沒有重復(fù)值的。我們可以利用這個(gè)屬性對數(shù)組進(jìn)行去重,以含有重復(fù)值的數(shù)組為參數(shù)實(shí)例化一個(gè)Set,得到的結(jié)果中將不會包括重復(fù)值 - 展開運(yùn)算符
...
數(shù)組可以展開為數(shù)組和對象;
對象可以展開為對象;不能展開為數(shù)組
Set可以展開為數(shù)組,但是如果展開為對象的話,會得到一個(gè)空對象。 - Map數(shù)據(jù)類型
最直觀的感受是,從Object的string——值對,變成了值——值對 - 修飾器@decorator
修飾器可以在編譯階段執(zhí)行代碼。用于修改類甚至于方法的行為
//修飾器函數(shù)1:為類加上靜態(tài)屬性isTestable
//修飾器函數(shù)的第一個(gè)參數(shù),就是所要修飾的目標(biāo)類
function testable(target) {
target.isTestable = true;
}
//修飾類的行為。寫在類上方,表示修飾器的目標(biāo)是這整個(gè)類
@testable
class MyTestableClass {}
console.log(MyTestableClass.isTestable) // true
解釋:
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
core-decorators.js core-decorators.js是一個(gè)第三方模塊,提供了幾個(gè)常見的修飾器,通過它可以更好地理解修飾器
@autobind:使得方法中的this對象,綁定原始對象
@readonly:使得屬性或方法不可寫
@override:檢查子類的方法是否正確覆蓋了父類的同名方法,如果不正確會報(bào)錯
@deprecate (別名@deprecated):在控制臺顯示一條警告,表示該方法將廢除.
https://blog.csdn.net/aaaaapipi/article/details/108040002
class
class就是es5中原型鏈實(shí)現(xiàn)的一個(gè)語法糖Promise
三種狀態(tài):pending(進(jìn)行中,初始化)、fulfilled(已成功)和rejected(已失?。?br> https://blog.csdn.net/qq_34645412/article/details/81170576
function asyncFun3(a){
let p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("內(nèi)3")
console.log(a)
resolve("異步,333333333333秒")
},3000)
})
return p
}
asyncFun1().then(function(a){
return asyncFun2(a)
}).then(function(a){
return asyncFun3(a)
})
Symbol
http://m.itdecent.cn/p/cad25435f5a4
Symbol 作為屬性名,遍歷對象的時(shí)候,該屬性不會出現(xiàn)在for...in、for...of循環(huán)中,也不會被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
但是,它也不是私有屬性,有一個(gè)Object.getOwnPropertySymbols()方法,可以獲取指定對象的所有 Symbol 屬性名。該方法返回一個(gè)數(shù)組,成員是當(dāng)前對象的所有用作屬性名的 Symbol 值。Proxy監(jiān)聽對象操作
區(qū)分變量類型的方法
對于原型鏈的理解
深拷貝的方法:
共有:展開運(yùn)算符、JSON轉(zhuǎn)字符串
Object:
Object.assign(obj1,obj2,obj3......)注意這里克隆的是引用,而該引用指向的內(nèi)存空間是沒有被拷貝的,
Array:[ ].concat(arr1,arr2,arr3......)
各種拷貝方法詳解
對象拷貝方法:
let obj={...a}是深拷貝,但是只拷貝指向。對于屬性指向的數(shù)組、對象,只拷貝指針,其內(nèi)容不重新開辟空間
let obj=Object.assign({},a)跟上面這種方式是一樣的
let obj=JSON.parse(JSON.stringify(a))這個(gè)倒是深拷貝了,缺點(diǎn)在于它在轉(zhuǎn)換時(shí)會丟失函數(shù)類型的屬性
自己寫工具方法,多層迭代。這個(gè)應(yīng)該是最靠譜的了
import { cloneDeep } from 'loadsh'loadsh是一個(gè)使用工具庫,deepClone僅僅是其中的一個(gè)方法,還有很多其他方法可用數(shù)組深拷貝
JSON,[].concat,slice等
數(shù)據(jù)類型
String(字符串類型)、Number(數(shù)字類型)、Boolean(布爾類型)、Array(數(shù)組類型)、Date(日期類型)。
ES6新增的數(shù)據(jù)類型有:
基本類型:Symbol
復(fù)雜類型:Set、Map、WeakSet、WeakMap、TypedArray
ES6中module能否使模塊按需加載
不能,因?yàn)閑s6中的module是靜態(tài)加載的,所以不能用于按需加載。靜態(tài)加載又叫編譯時(shí)加載,與運(yùn)行時(shí)加載相反,那么react中import無法使用變量、import之前不能存在語句,也就可以解釋為:因?yàn)閕mport是在編譯的時(shí)候加載的,這個(gè)時(shí)候 程序還沒運(yùn)行,語句也就不會執(zhí)行,變量也不會被運(yùn)算和賦值。
https://www.aisoutu.com/a/581405
async\await函數(shù)和generator函數(shù)相比,有哪些優(yōu)點(diǎn)
http://m.itdecent.cn/p/a0e6b9755129
- generator函數(shù)需要調(diào)用next()指令來向下執(zhí)行,async不需要,async有內(nèi)置的執(zhí)行器,可以向運(yùn)行正常函數(shù)一樣運(yùn)行就可以了
- 像將于generator的*和yield,async/await的語義化更加明確。async是“異步的簡寫,await可以視為async wait。
- 適應(yīng)性更廣,yield 命令后面只能是 Thunk 函數(shù)或 Promise 對象,而 async 函數(shù)的 await 命令后面,可以跟 Promise 對象和原始類型的值(數(shù)值、字符串和布爾值,但這時(shí)等同于同步操作)。await是一個(gè)表達(dá)式,它有返回值
- async返回一個(gè)promise對象,可以調(diào)用catch和then
字符串模板、DOM模板、模板字符串
es6交換兩個(gè)變量的值
let a=1
let b=2; //這個(gè)分號必須要有,雖然還不太明白原因,但是沒有就會報(bào)錯
[a, b] = [b, a]
console.log(a,b)
模板字符串的好處
- 可以多行,無需使用反斜杠
- 使用${}就能進(jìn)行拼接,更加簡潔優(yōu)美
arguments和rest參數(shù)的區(qū)別
- arguments對應(yīng)的是全部的參數(shù),而rest只對應(yīng)那些沒有形參的參數(shù)。
- arguments不是真正的數(shù)組,而rest卻是數(shù)組的實(shí)例,所以可以使用數(shù)組所有的方法。arguments如果想用數(shù)組的地方法,還需要經(jīng)過一次轉(zhuǎn)換
- auguments有自己特有的屬性,如callee
es5與es6繼承的區(qū)別是什么?
1.ES5的繼承實(shí)質(zhì)上是先創(chuàng)建子類的實(shí)例對象,然后再將父類的方法添加到this上(Parent.apply(this)).
2.ES6的繼承機(jī)制完全不同,實(shí)質(zhì)上是先創(chuàng)建父類的實(shí)例對象this(所以必須先調(diào)用父類的super()方法),然后再用子類的構(gòu)造函數(shù)修改this。
3.ES5的繼承時(shí)通過原型或構(gòu)造函數(shù)機(jī)制來實(shí)現(xiàn)。
4.ES6通過class關(guān)鍵字定義類,里面有構(gòu)造方法,類之間通過extends關(guān)鍵字實(shí)現(xiàn)繼承。
手寫4種繼承
- 原型繼承
Son.prototype=father;
function Father(){
this.firstName="李";
}
var father=new Father();
Father.prototype.lastName="名";
function Son(){
this.firstName="張";
this.sex="男";
}
// 子類原型繼承父類的實(shí)例
Son.prototype=father;
var son=new Son();
console.log(son.firstName,son.lastName,son.sex); //張 名 男
核心是子類原型繼承父類實(shí)例
firstName子類有,直接輸出張。lastName自己沒有,去原型鏈上找到并輸出名
1.實(shí)例既是父類的實(shí)例也是子類的實(shí)例
2.父類新增原型方法或是原型屬性子類都可以訪問到。
3.簡單易實(shí)現(xiàn)。
缺點(diǎn):
1.無法實(shí)現(xiàn)多繼承(多繼承就是將多個(gè)對象和成員交給當(dāng)前對象);
2.創(chuàng)建子類實(shí)例時(shí),無法向父類傳參.
- 構(gòu)造繼承
Father.call(this,name,age,sex)
function Father(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
function Son(name,age,sex,gf){
// call方法第一個(gè)值寫this指向
Father.call(this,name,age,sex)
this.gf=gf;
}
var son=new Son("李飛",20,"男","張曉麗");
console.log(`${son.name}今年${son.age}歲,性別${son.sex},女朋友叫${son.gf}`);//李飛今年20歲,性別男,女朋友叫張曉麗
核心是把子類用父類的構(gòu)造函數(shù)作為自己的構(gòu)造函數(shù)
Father.call(this,name,age,sex)是調(diào)用父類的構(gòu)造函數(shù),但是使用的是子類的this。通過父類構(gòu)造函數(shù)構(gòu)造完畢后,子類的name、age、sex等屬性已經(jīng)具備。再在此基礎(chǔ)上添加this.gf=gf;去修改父類沒有處理的屬性即可
特點(diǎn):
1.只繼承了父類的構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性
2.可以實(shí)現(xiàn)多繼承(多次使用call)
3.可以向父類傳參
4.無法實(shí)現(xiàn)構(gòu)造函數(shù)的復(fù)用(每次都要從新調(diào)用)
5.每個(gè)新實(shí)例都有父類構(gòu)造函數(shù)的副本。
- 組合繼承
//就是構(gòu)造繼承加一句
Son.prototype=new Father();
特點(diǎn):
1.可以繼承父類原型的屬性,可以傳參,可以復(fù)用。
2.每個(gè)新實(shí)例引入的構(gòu)造函數(shù)是私有的
3.調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存)
寄生繼承
寄生組合繼承
es6 class extend繼承
CSS3
新特性、div盒子居中、清除浮動、動畫、canvas、畫三角形、定位的種類和區(qū)別、彈性布局
transform 變換:分為2d轉(zhuǎn)換和3d轉(zhuǎn)換
transition 過渡:控制變換的速度
translate 變換的一種:簡單位移變化
keyframe{ from to} 也可以是百分比
漸變:線性漸變與徑向漸變
用純css3實(shí)現(xiàn)等邊三角形
等邊三角形
#triangle{
border-style: solid;
width: 0px;
border-width: 173px 100px 0px 100px;
border-color: aqua transparent transparent transparent;
}
30-60°直角三角形
#triangle{
border-style: solid;
width: 0px;
border-width: 173px 100px 0px 0px;
border-color: aqua transparent transparent transparent;
}
div盒子居中的方法
垂直水平都能居中:
-
方法一:margin:auto
關(guān)鍵就在于,子元素設(shè)置絕對定位,上下左右一定都要設(shè)置為0,然后把margin設(shè)置auto就好了
上下都取0,可以實(shí)現(xiàn)垂直居中
左右都取0,實(shí)現(xiàn)水平居中
.chl_box {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background: #00FFFF;
}
+方法二:知道子元素寬高的情況下
子元素top:50%,margin:-50px(假設(shè)子元素高度為100)
- 方法三:父子元素寬高都知道的情況下
子元素margin:50px(假設(shè)父元素高-子元素高=100px) -
方法四:彈性布局居中:需要被操作的是父容器
1、flex-direction 用于定義彈性布局的主軸,默認(rèn)值就是橫向從左向右
2、 justify-content 定義主軸上面的對其方式,設(shè)為center。(此時(shí)默認(rèn)水平居中)
3、align-items 定義交叉軸上的對齊方式,設(shè)為center。(此時(shí)默認(rèn)垂直居中)
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
display: flex;
justify-content: center;
align-items: center;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
}
-
方法五:translate居中 ie9一下瀏覽器不支持
首先我們讓子元素左側(cè)距離父元素左邊為父元素的50%,再用translate倒退子元素的50%
translate的作用是轉(zhuǎn)換。轉(zhuǎn)換的錨點(diǎn)是整個(gè)div的中心
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
position: relative;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
+方法六: table-cell居中
這種的話就是將父元素轉(zhuǎn)換成表格單元格顯示,然后使用垂直居中實(shí)現(xiàn)
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
display: table-cell;
vertical-align: middle;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
margin: 0 auto;
}
-
方法七:不確定寬高居中
這種的原理其實(shí)相當(dāng)于在子元素周圍加了一圈邊框,致使子元素只能有這么寬和這么高,是沒有辦法去改變子元素寬高的。例如這里left的值一改變成5%,整個(gè)子元素的寬也會改變
子元素要設(shè)置為絕對定位
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
position: relative;
}
.chl_box {
background: #00FFFF;
position: absolute;
left: 25%;
right: 25%;
top: 25%;
bottom: 25%;
}
僅能水平居中
+方法一:子元素relative定位是,margin:auto
