1.void,null,undefined,never,NaN
void:無傳回值,隻能指派undefined和null
null:空值,表示不存在
undefined:未定義,聲明了但沒有指派,對象沒有指派的屬性,對象沒有傳回值
never:永不存在的值的類型,是
抛出異常或根本沒有傳回值的函數表達式
的傳回值類型
NaN:和任何值都不相等,包括自身
2.const和readonly
const:修飾的常量是靜态屬性。聲明時必須指派,指派後不能再改變,實際上是變量至指向的記憶體位址所儲存的資料不改動,對于簡單類型,值就儲存在變量指向的記憶體位址。對于
複合類型的資料(引用類型)
,const隻能保證這個指針是固定的,至于指針指向的資料結構是否可變就不能控制。
readonly :修飾的常量是動态屬性(值在運作的時候獲得)。可以在聲明或構造函數中初始化
3.接口和泛型
接口:定義了要遵循的類的文法,實作接口的類必須實作它的所有成員。不同類之間公有的屬性和方法可以抽象為一個接口
泛型:解決類,接口,方法的複用性(
傳入什麼類型就傳回什麼類型
),以及對不特定資料類型的支援
4.匿名函數和箭頭函數
匿名函數:聲明是沒有任何命名辨別符的函數,在運作時動态聲明的,可以接受輸入和傳回輸出,在初始建立之後通常是不可通路的
let fun=function(x:number,y:number):number{
return x+y;
}
箭頭函數:相當于匿名函數并且簡化了函數的定義。沒有prototype原型,所有箭頭函數本身沒有this,this在箭頭函數中已經按照詞法作用域綁定了,this指向是固定的。沒有構造函數
箭頭函數的this指向該函數所在的作用域指向的對象
5.findindex(),indexof(),forEach()
findindex()對于空數組不執行,也不使适用于字元串。範圍更廣,可以根據不同條件進行查詢。傳回的是符合查詢條件的第一個值的
索引
.
let arr = [1, 1, 2, 2, 8, 8,5,4]
function check(a) {
return a>1
}
let result = arr.findIndex(check)
console.log(result) //2
indexof()傳回某個指定的字元串值在字元串中首次出現的位置。空數組和字元串都會執行。
forEach() 對于空數組不執行,用于調用數組的每個元素,并将元素傳遞給回調函數。
示例代碼
6.浏覽器重定向頁面,浏覽器打開新頁面
重定向頁面
window.location.href="https://www.baidu.com/"
window.location.replace("https://www.baidu.com/")
打開新頁面,視窗
7.splice()與slice()
splice(2,7) 表示從索引2開始的位置,截取7個長度,
會傳回截取後的資料
slice(2,7) 表示從索引2開始的位置,截取到6索引的位置(不包含7),
不會改變原數組
8.promise
promise:是一個構造函數,可以執行個體化promise執行個體。有兩個函數resolve(成功時的回調函數)和reject(失敗後的回調函數)。在promise的構造函數的prototype屬性上有then()方法。
9.px,em,rem
px:像素px是相對于顯示器螢幕分辨率而言的。缺點沒有彈性,IE可能不相容
em:參考物是父元素的font-size,具有繼承的特點。相對于目前對象内文本的字型尺寸。如目前對行内文本的字型尺寸未被人為設定,則相對于浏覽器的預設字型尺寸。
rem:rem是相對于根元素html, 不會被它的父元素影響
10.css選擇器
标簽選擇器div 類選擇器. id選擇器# 子類選擇器> 兄弟選擇器~ 全局選擇器* 相鄰選擇器+ 包含選擇器 僞類選擇器(:hover nth-child(n):)
僞類(before,after)與僞類選擇器根本差別:是否建立了新元素
11.position有哪些屬性
relative:相對于原來位置移動,元素設定此屬性之後仍然處在文檔流中,不影響其他元素的布局
absolute:元素會脫離文檔流,如果設定偏移量,會影響其他元素的位置定位。絕對定位是相對于元素最近的已定位的祖先元素(即是設定了絕對定位或者相對定位的祖先元素)。如果元素沒有已定位的祖先元素,那麼它的位置則是相對于最初的包含塊(body)
fixed:相對于浏覽器視窗,生成固定定位
inherit:繼承父元素的position 屬性的值
static:預設值。沒有定位,元素出現在正常的流中
sticky:粘性定位,該定位基于使用者滾動的位置。
12.垂直水準居中
<body>
<div id="aaa">
<div id="bbb"></div>
</div>
</body>
方法一 相對絕對定位
body{
margin: 0px;
padding: 0px;
}
#aaa{
position: relative;
width: 500px;
height: 500px;
background: red;
}
#bbb{
position:absolute;
width: 300px;
height: 300px;
background: pink;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
方法2 flex布局
body {
margin: 0px;
padding: 0px;
}
#aaa {
display: flex;
width: 500px;
height: 500px;
justify-content: center;
align-items: center;
background-color: red;
}
#bbb {
width: 300px;
height: 300px;
background-color: pink;
}
13.清除浮動
方法一:添加額外标簽,并在标簽中使用clear:both (不推薦)
方法二:添加僞類元素(::after),設定clear:both。注意必須塊級元素且IE8以上
14.行内元素與塊級元素
塊級元素:獨占一行,預設情況下,其寬度自動填滿其父元素寬度
塊級元素可以設定width,height,margin,padding
行内元素:不會獨占一行,行内元素設定width,height屬性無效,它的長度高度主要根據内容決定。行内元素的margin和padding屬性
水準方向有效果,垂直方向沒有效果
15.js與ts的差別
ts是js的超集。js是腳本語言,ts是面向對象程式設計語言。ts支援可選參數,靜态類型,接口,js不支援。ts在編譯時就能報錯,js運作時才暴報錯。ts是強類型語言,可以明确知道參數類型。
16.axios,ajax,fetch
axios 基于promise用于浏覽器和node.js的http用戶端。是對ajax的封裝,安全性更高。有then鍊,可以異步程式設計
function Callback<T>(promise: Promise<T>) {
return promise
.then((data) => { data })
.catch((err) => { err })
}
function test() {
return Callback(axios.get(""))
}
fetch隻對網絡請求報錯,對400,500都當做成功的請求,需要封裝去處理,是原生js,沒有使用XMLHttpRequest對象
ajax底層使用XMLHttpRequest,
Ajax引擎在用戶端運作,特點是實作局部重新整理,支援異步請求的技術。不支援浏覽器back,暴露了與伺服器互動的細節
XmlHttpRequest可以在使用JavaScript向伺服器提出請求并處理響應,而不阻塞使用者。通過XMLHttpRequest對象,Web開發人員可以在頁面加載以後進行頁面的局部更新。
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
17.http狀态碼
2xx:伺服器成功處理請求
例如:200 (成功)表示用戶端發送的請求在伺服器被正常的處理了。
3xx:狀态碼用于重定向
例如:301 永久性重定向,請求的資源被配置設定了新的URI,以後都使用這個。
302 臨時性重定向,請求的資源被配置設定了新的URI,本次使用這個。
4xx:請求錯誤,用戶端或許有錯誤
例如:404 伺服器找不到資源 403 請求的資源通路被拒絕
5xx:伺服器錯誤
例如:500 伺服器執行請求時發送異常 503 伺服器暫時無法處理請求
18.a标簽的href和target屬性
href屬性用于指定超連結目标的url
target屬性規定在何處打開連結文檔
_blank 在新視窗打開連結
_self 在目前視窗打開連結(預設)
_top 在整個視窗中打開連結
_parent 在父架構集中打開連結
alt屬性規定在圖像無法顯示時的替代文本
title屬性規定的是在滑鼠以上元素時顯示的文本
19.for in 與 for of
for in 适合周遊對象,數組,通常用來周遊對象的鍵名,原型鍊上所有屬性都會呗通路,用hasOwnProperty()解決
for of (es6)适合周遊樹,數組,數組對象,字元串等,通常用來周遊鍵值
20.for循環與setTimeout()
https://www.jb51.net/article/122489.htm
21.網站的登入狀态是如何儲存的,完整的登入流程是什麼?
通過cookie儲存登入狀态。cookie存儲token,每次請求到後端伺服器都會帶上token,進而驗證使用者是否登入。
1.用戶端請求背景登入接口。
2.背景驗證通過後,将使用者的登入狀态儲存至cookie并寫入用戶端。
3.用戶端再次登入網站,請求login接口時,背景直接從用戶端擷取到該使用者寫入cookie的登入狀态。
4.通過對該狀态的驗證,确認使用者是否需要再次登入。
5.如cookie過期,則跳轉至登入頁;如未過期,則直接顯示為已登入狀态。
22.DOCTYPE作用
聲明位于文檔中最前面的位置,處于标簽之前。可以告知浏覽器文檔使用何種規範解析頁面(html,xhtml)
23.call,apply,bind
let a=[1,2,3,4,5]
console.log(Math.Max,call(null,2,3,4,5,6)) //6
console.log(Math.Max,apply(null,[2,3,4,5,6])) //6
let b=Math.Max,bind(null,2,3,4,5,6)
b() //6
call和apply直接執行,bind事先将方法的this改為我們想要的結果,需要時再調用執行。apply的第二個參數是以數組形式傳入的。call和bind以清單參數傳遞。
23.src,href
href是元素或文檔與指定資源聯通,需要的時候再引用
src是下載下傳後嵌入構成文檔直接内容
24. get post
get:長度限制為2k,參數在url可見,速度更快
post:沒有長度限制,參數寫在請求頭裡面,安全性更高,速度不如get(因為在第三次握手時,會發送post請求頭,伺服器才會傳回100 continue ,用戶端此時才發送資料。而get在第三次握手時就已經攜帶了資料)
25.三次握手
why:為了保證可靠的資料傳輸,防止無效的請求又發送到伺服器。
ACK=1 确認号有效
SYN=1 請求建立連接配接
seq 序列号
ack 期望下一次接收到的序列号

26.jsonp跨域
用戶端通過script标簽的src屬性發送請求,并且定義一個回調函數。伺服器端響應請求後會傳入參數動态執行回調函數,就實作了跨域。因為是script标簽,是以傳回的資料會直接當作js語言執行就會産生錯誤,是以需要回調函數的存在,關鍵是伺服器傳回的資料外層需要需要包裹一層函數
react 使用代理中間件 http-proxy-middleware實作跨域請求
const proxy = require('http-proxy-middleware')
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(createProxyMiddleware('/api',{
target:'http://localhost:3300',
changeOrigin: true
}))
};
27.xss,CSRF攻擊
xss:跨站腳本攻擊,利用網站對使用者輸入沒有進行限制或過濾,進而在頁面中嵌入某些代碼,當别的使用者通路到該網頁時,會執行對應的代碼,進而使得攻擊者可以擷取。
防禦:設定Cookie的屬性為Http only,這樣js就無法擷取Cookie值
CSRF攻擊:跨域請求僞造,
防禦:使用随機token或驗證碼
28.浏覽器輸入url到渲染的過程
1.首先是域名解析,解析到對應的ip位址
2.三次握手,請求建立連接配接
3.發送http請求,伺服器響應請求,浏覽器擷取html源碼
4.解析html并且建構DOM樹
5.解析css生成css對象模型
6.dom樹和css附着在一起呈現reader tree(重排和重繪)
7.浏覽器計算節點的位置和樣式進行布局
29.重排reflow和重繪repaint
重排:元素的規模,位置和隐藏等改變時,都會引起回流。
引起重排的條件:首次渲染,删除或增加dom元素,元素位置的改變,尺寸的改變,視窗尺寸的改變,讀取某些元素的值。一定會引起重繪。
重繪:元素的外觀改變觸發的浏覽器行為,浏覽器會根據元素的新屬性重新繪制,呈現新的外觀。如:color
優化:
1.合并多次dom的修改
2.直接改變元素的類名,切換類名
3.經常進行重排的元素設定position:absolute和fixed ,脫離文檔流,不會影響到其他元素
4.避免使用table布局,一個小改動會引起整個table重新布局
5.經常通路元素屬性的操作時,将屬性賦給局部變量進行計算。
30.new一個對象的過程
其實是一種繼承的方式, 通過new,執行個體與構造函數通過原型鍊連接配接了起來出來,是以執行個體能通路到構造函數的屬性。改變了構造函數的this指向
ps:
每個對象的__proto__屬性都指向原型對象
每個構造函數都有prototype原型對象
prototype原型對象裡都有constructor指向它的構造函數
31.盒子模型
所有的html元素都可以看作為盒模型,即content+padding+border+margin
1.标準模型:box-sizing:content-box
内容大小(寬高):content的大小,即width和height
設定padding時,content大小不變,整體變大
2.IE模型:box-sizing:border-box
内容大小:content(width,height)+padding+border
因為是包括padding的,是以設定padding時,元素會被擠壓,整體不變
32.什麼是flex布局
彈性布局,任何元素都可以指定為flex,随着網頁的大小自适應布局。采用flex布局的元素稱為容器,子元素稱為項目。設定了flex之後,float,clear等屬性失效。
flex(flex-grow、flex-shrink、flex-basis):
flex-grow定義項目的放大比例,預設為0,即如果存在剩餘空間,也不放大
flex-shrink 定義了項目的縮小比例,預設為1,即如果空間不足,該項目将縮小
flex-basis給上面兩個屬性配置設定多餘空間之前, 計算項目是否有多餘空間, 預設值為 auto, 即項目本身的大小
flex:auto代表 1 1 auto
flex:1代表 1 1 0
33.BFC
塊級上下文,獨立的渲染區域。區域内部與外部無關。BFC中的所有子元素的左外邊都會與父塊的左邊接觸。
作用:
1.防止被浮動的元素擋住
2.解決margin塌陷的問題。因為同一BFC的兩個box之間的margin以大的為準
3.自适應兩欄布局
4.清除浮動(BFC計算高度時會包括浮動的高度,會清除内部子元素浮動的影響,父元素在計算其高度時,加入了浮動元素的高度,“順便”達成了清除浮動的目标,是以父元素就包裹住了子元素)
如何建立BFC:
1.float不為none
2.overflow不為visible
3.position不為static或relative
4.display是lnline-block,inline-flex,flex,table-cell,table-caption
34.typyof和instanceof
typeof用來判斷基本資料類型,傳回的是字元串,但是對于null,object和array傳回的都是object。
instanceof一個變量是否屬于某個對象的執行個體,傳回的是Boolean類型,判斷某個構造函數的prototype屬性是否存在對象的原型鍊上。
下面手寫實作一下instanceof方法
function test_instanceof(L, R) {
let LL = L.__proto__
let RR = R.prototype
while (true) {
if (LL === null) return false
if (RR === LL) return true
LL=LL.__proto__
}
}
function t() { }
let a = new t()
console.log(test_instanceof(a,t)) //true
console.log(test_instanceof(a,Object)) //true
35.構造函數和普通函數的差別
構造函數可以生成執行個體對象
調用方式不同:構造函數用new關鍵字調用
首字母大小寫:構造函數首字母一般大寫
this指向不同:普通函數this指向window,構造函數的this指向建立的執行個體對象。
36.原型,原型對象
原型對象:構造函數prototype指向的就是原型對象
原型:函數有原型,函數的這個原型指向一個對象即原型對象
37.js繼承
1.原型鍊繼承:父類的執行個體充當子類的原型對象
缺點:父類的屬性是所有子類共享的,不能多繼承
function father() { }
function son() {}
son.prototype=new father()
2.構造函數繼承:借用父類的構造函數來增強子類執行個體,等于是把父類的執行個體屬性複制一份給子類執行個體,可以多繼承
缺點:無法實作函數的複用,執行個體并不是父類的執行個體,隻是子類的執行個體,隻繼承父類,不繼承原型
function Super(val){
this.val = val;//可以傳遞參數
this.arr = [1];
}
function Sub(val){
Super.call(this,val);//核心代碼
//通過call()和apply()方法在新建立的對象上執行構造函數
}
3.組合式繼承:使用原型鍊實作對原型屬性和方法的繼承,而通過構造函數來實作對執行個體屬性的繼承。
function Parent(name){
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function(){
console.log(this.name);
}
function Child(name,age){
Parent.call(this,name);// 第二次調用 Parent()
this.age = age;
}
Child.prototype = new Parent(); // 第一次調用 Parent()
38.call,apply,bind
第一個參數都是this要指向的對象,call第二個參數是參數清單的方式傳入,apply第二個參數是數組的方式傳入
call與apply是立即調用,bind是傳回對應函數,需要時調用
function show(x){
console.log(x);
}
let person={
name:"aa",
};
show.call(person,"男");
show.apply(person,["女"]);
let ss=show.bind(person,"111");
ss()
bind的實作
39.深拷貝的實作
40.promise
Promise,就是一個對象,用來傳遞異步操作的消息,可以進行異步操作
async await 解決回調地獄,文法糖
async function test1(){
console.log("11")
await test()
console.log("22")
}
test1()
new Promise(function (resolve) {
console.log("33")
resolve();
}).then(function () {
console.log("44")
})
function test() {
console.log("test")
}
//11 test 33 22 44
macro-task(宏任務):包括整體代碼script,setTimeout,setInterval
micro-task(微任務):Promise.then,process.nextTick
補充一個宏任務和微任務
41.強緩存和協商緩存
浏覽器第一次向伺服器發起請求時,伺服器響應請求後,浏覽器端會進行緩存。伺服器會将最後一次修改時間last-modified發送給用戶端進行記錄,同時還會生成并發送Etag
強緩存
:浏覽器請求資源時,會擷取該資源緩存的header資訊,根據cache-control判斷是否從緩存中擷取資源。
cache-control:max-age=31536000,public,immutable
max-age:緩存時間(s)
public:伺服器和浏覽器都可以緩存
immutable:資源永遠改變(使用者重新整理浏覽器也不發送請求)
協商緩存
:浏覽器每次請求資源時,向伺服器發送請求并且攜帶header中的Etag和last-modified,伺服器判斷是否改變,如果改變就傳回新的資源和新的etag,last-modified以及200狀态碼。如果沒有改變,傳回304狀态碼,浏覽器就讀取本地資源。
注意伺服器端header會改變
// response header
etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT
// request header 變為
if-none-matched: '5c20abbd-e2e8'
if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
已經有last-modified為什麼要使用etag
1.有些資源的改變在1s内改變多次,last-modified對這種操作無法精确
2.某些請求是周期性的,沒有修改内容,
3.某些伺服器無法精确到最後修改時間
42.JSON.parse()和JSON.stringity()
JSON.parse():一個字元串中解析出json
JSON.stringity():從一個對象中解析出字元串