一、CSS面試篇
1、盒子模型
css中的盒子模型包括IE盒子模型和标準的W3C盒子模型。其盒子模型還是要歸宗于box-sizing的屬性,盒子模型對應的分被為border-box,content-box。所謂的标準盒子模型(border-box):width = 左右border+左右padding+contentwidth,而我們的IE盒子模型(border-box): width = content+padding+border 元素指定的任何内邊距和邊框都将在已設定的寬度和高度内進行繪制。
2、前端一像素問題(畫一條0.5px的線)
方法一:transform:scaleY(0.5)使用僞元素設定1px的邊框,然後對邊框進行縮放(scaleY)
實作思路:
1、設定目标元素的參考位置
2、給目标元素添加一個僞元素before或者after,并設定絕對定位
3、給僞元素添加1px的邊框
4、用box-sizing: border-box 屬性把邊框都包進寬和高裡面
5、寬和高設定為 200%
6、整個盒子模型縮小為0.5
7、調整盒子模型的位置,以左上角為基準 transform-origin: 0
方法二: border-image 設定圖檔的邊框
3、transition和animation的差別
Animation和transition大部分屬性是相同的,他們都是随時間改變元素的屬性值,他們的主要差別是transition需要觸發一個事件才能改變屬性,
而animation不需要觸發任何事件的情況下才會随時間改變屬性值,并且transition為2幀,從from .... to,而animation可以一幀一幀的。
4、不定高的DIV居中
1.使用flex
在父盒子設定display: flex; justify-content: center;align-items: center
複制代碼2.使用css的transform
父盒子設定:display:relative
Div 設定: transform: translate(-50%,-50%);position: absolute;top: 50%;left: 50%;
複制代碼3.display:table-cell
父盒子設定:display:table-cell; text-align:center;vertical-align:middle;
Div 設定: display:inline-block;vertical-align:middle;
複制代碼5、浮動相應連結
特性:浮動元素影響的不僅是自己,他會影響周圍元素對其進行環繞
為什麼要清除浮動?(解決父元素高度坍陷問題)
一個塊級元素如果沒有設定height,其height由子元素撐開,對子元素使用了浮動之後,子元素就會脫離文檔流也就是說,父及元素中沒有内容可以撐開其高度,這樣父級元素height就會被忽略。這就是所謂的高度坍塌
如何清除浮動
1.給父級元素定義高度
2.讓父級元素也浮動
3.父級定義display:table
4.父元素設定overflow:hidden
5.clearfix:使用内容生成的方式清除浮動
.clearfix:after { // :after選擇器向標明的元素之後插入内容
content:""; // 生成内容為空
display: block; // 塊級元素顯示
clear:both; // 清除前面元素
}
不破壞文檔流,沒有副作用
複制代碼6、css選擇器分類
基本的:
1.id選擇器(id="name")
2.類選擇器(class="head")
3.标簽選擇器(body, div, ul, li)
4.全局選擇器(*)
複雜的:
1.組合選擇器(.head .head_logo)
2.後代選擇器 (#head .nav ul li 從父集到子孫集)
3.群組選擇器 (div, span, img {color:Red} 具有相同樣式的标簽分組顯示)
4.繼承選擇器
5.僞類選擇器(連結樣式,a元素的僞類)
6.子選擇器(div>p, 帶大于号>)
7.CSS相鄰相鄰兄弟選擇器(h1+p, 帶加号+)
複制代碼
優先級:
不同級别:總結排序:!important > 行内樣式 > ID選擇器 > 類選擇器 > 标簽 > 通配符 > 繼承 > 浏覽器預設屬性
1.屬性後面加!import 會覆寫頁面内任何位置定義的元素樣式
2.作為style屬性寫在元素内的樣式
3.id選擇器
4.類選擇器
5.标簽選擇器
6.通配符選擇器(*)
7.浏覽器自定義或繼承
同一級别:後寫的會覆寫先寫的
css選擇器的解析原則:選擇器定位DOM元素是從右往左的方向,這樣可以盡早的過濾掉一些不必要的樣式規則和元素
7、行内元素和塊元素
塊元素
行内元素
塊元素會獨占一行,預設情況下,其寬度自動填滿父元素寬度 行元素不會占據一行,會一直排在一行,直到一行排不下
行元素沒有寬度和高度屬性,塊級元素即使設定了寬度,還是會獨占一行
塊級元素: div p forn ul li h1-h6
行内元素:span img input a i
注意:對于行内元素,font-size指定 他們的content area的高度,由于inline box = 上下的helf-leading,如果leading為0,在這種情況下,font-size指定了inline box的高度font-size指的是字型的高度,但是不能指定每個字形給定字型高度下的實際高度,導緻了span的高度大于line-height
8、如何畫一個三角形
設定寬高,然後用border去畫
width: 0;
height: 0;
border-bottom: 100px solid cyan;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
複制代碼9、使元素消失的方法
visibility:hidden、display:none、z-index=-1、opacity:0
1.opacity:0,該元素隐藏起來了,但不會改變頁面布局,并且,如果該元素已經綁定了一些事件,如click事件也能觸發
2.visibility:hidden,該元素隐藏起來了,但不會改變頁面布局,但是不會觸發該元素已經綁定的事件
3.display:node, 把元素隐藏起來,并且會改變頁面布局,可以了解成在頁面中把該元素删掉
10、為什麼css放在頂部而js寫在後面
1.浏覽器預先加載css後,可以不必等待HTML加載完畢就可以渲染頁面了
2.其實HTML渲染并不會等到完全加載完在渲染頁面,而是一邊解析DOM一邊渲染。
3.js寫在尾部,主要是因為js主要扮演事件處理的功能,一方面很多操作是在頁面渲染後才執行的。另一方面可以節省加載時間,使頁面能夠更加的加載,提高使用者的良好體驗
但是随着JS技術的發展,JS也開始承擔頁面渲染的工作。比如我們的UI其實可以分被對待,把渲染頁面的js放在前面,時間處理的js放在後面
二、布局面試
1、flex彈性布局
可以簡單的使一個元素居中(包括水準和垂直居中)栅格式系統布局,bootstrap grid
2、三欄是布局
三欄是布局(兩邊兩欄寬度固定,中間欄寬度自适應)
方案一:position(絕對定位法) center的div需要放在最後面
絕對定位法原理将左右兩邊使用absolute定位,因為絕對定位使其脫離文檔流,後面的center會自然流動到他們的上賣弄,然後margin屬性,留出左右兩邊的寬度。就可以自适應了。
方案二:float 自身浮動法 center的div需要放到後面
自身浮動法的原理就是對左右使用float:left和float:right,float使左右兩個元素脫離文檔流,中間的正常文檔流中,使用margin指定左右外邊距對其進行一個定位。
方案三(聖杯布局):原理就是margin負值法。使用聖杯布局首先需要在center元素外部包含一個div,包含的div需要設定float屬性使其形成一個BFC,并且這個寬度和margin的負值進行比對
3、左邊定寬,右邊自适應
方案一:左邊設定浮動,右邊寬度設定100% .left{float:left} .right:{width:100%}
方案二:左設定浮動,右用cacl去補寬度計算 .left{float:left} .right:{width:cacl(100vw-200px}
方案三:父容器設定display:flex right部分是設定flex:1
方案四:右邊div套個包裹、并前置、左及包裹 雙浮動
4、水準居中
行内元素居中(父元素text-align:center)
塊狀元素居中(塊狀元素沒發用text-align)
1.寬度一定:margin:auto
2.寬度不定:塊級變行内,然後在父上text-aligin
複制代碼5、BFC
了解:BFC是css布局的一個概念,是一塊獨立的渲染區域,一個環境,裡面的元素不會影響到外部的元素
如何生成BFC:(脫離文檔流)
【1】根元素,即HTML元素(最大的一個BFC)
【2】float的值不為none
【3】position的值為absolute或fixed
【4】overflow的值不為visible(預設值。内容不會被修剪,會呈現在元素框之外)
【5】display的值為inline-block、table-cell、table-caption
BFC布局規則:1.内部的Box會在垂直方向,一個接一個地放置。
2.屬于同一個BFC的兩個相鄰的Box的margin會發生重疊
3.BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此, 文字環繞效果,設定float
4.BFC的區域不會與float box重疊。
5.計算BFC的高度,浮動元素也參與計算
BFC作用:1.自适應兩欄布局
2.可以阻止元素被浮動元素覆寫
3.可以包含浮動元素---清除内部浮動 原理::觸發父div的BFC屬性,使下面的子div都處在父div的同一個BFC區域之内
4.分屬于不同的BFC時,可以阻止margin重疊
三、js面試篇
1、前端事件流
事件流描述的是從頁面中接受事件的順序,可以分為:事件捕獲階段 處于目标階段 事件冒泡階段其中需要主要的是addeventListener這個函數 最後這個布爾值參數如果是true,表示在捕獲階段調用事件處理程式;如果是false,表示在冒泡階段調用事件處理程式。
1、事件捕獲階段:實際目标div在捕獲階段不會接受事件,也就是在捕獲階段,事件從document到再到就停止了
2、處于目标階段:事件在div發生并處理,但是事件處理會被看成是冒泡階段的一部分。
3、冒泡階段:事件又傳播回文檔
阻止冒泡事件event.stopPropagation()
function stopBubble(e) {
if (e && e.stopPropagation) { // 如果提供了事件對象event 這說明不是IE浏覽器
e.stopPropagation()
} else {
window.event.cancelBubble = true //IE方式阻止冒泡
阻止預設行為event.preventDefault()
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault()
// IE浏覽器阻止函數器預設動作的行為
window.event.returnValue = false
複制代碼事件如何先捕獲後冒泡:
在DOM标準事件模型中,是先捕獲後冒泡。但是如果要實作先冒泡後捕獲的效果,對于同一個事件,監聽捕獲和冒泡,分别對應相應的處理函數,監聽到捕獲事件,先暫緩執行,直到冒泡事件被捕獲後再執行捕獲事件。
哪些事件不支援冒泡事件:
滑鼠事件:mouserleave mouseenter
焦點事件:blur focus
UI事件:scroll resize
2、事件委托(提高性能)
簡介:事件委托指的是,不在事件的(直接dom)上設定監聽函數,而是在其父元素上設定監聽函數。通過事件冒泡,父元素可以監聽到子元素上事件的觸發通過判斷事件發生元素DOM的類型,來做出不同的響應。
舉例子: 最經典的就是ui和li标簽的事件監聽,比如我們在添加事件的時候,采用事件委托機制,不會在li标簽上直接添加,而是在ul父元素上添加
好處:可以比較合适動态元素的綁定,新添加的子元素也會監聽函數,也可以有事件觸發機制
3、js的new操作符做了什麼
new操作符建立了一個空對象,這個對象原型指向構造函數的prototype,執行構造函數後傳回這個對象。如果不要父類的屬性跟方法,在函數的prototype上去new這個父類。
4、this的指向
1、當函數作為對象的方法被調用時,this就會指向該對象。
2、作為普通函數,this指向window。
3、構造器調用,this指向傳回的這個對象。
4、箭頭函數 箭頭函數的this綁定看的是this所在函數定義在哪個對象下,就綁定哪個對象。如果有嵌套的情況,則this綁定到最近的一層對象上
4.1、箭頭函數this的原理:
this指向的固定化,并不是因為箭頭函數内部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,導緻内部的this就是外層代碼塊的this。正是因為它沒有this,是以也就不能用作構造函數。
4.2、怎麼改變this的指向呢?
1.使用es6的箭頭函數;2.在函數内部使用that = this;3.使用apply,call,bind; 4.new執行個體化一個對象
4.3、bind,apply,call的差別
通過apply和call改變函數的this指向,他們兩個函數的第一個參數都是一樣的表示要改變指向的那個對象,第二個參數,apply是數組,而call則是arg1,arg2...這種形式。bind一個是傳回一個函數,并不會立即執行第二個是帶參數(第一個參數要指向的this,後面的的參數用來傳遞
5、深淺拷貝參考連結
基本類型
引用類型
基本類型:undefined,null,Boolean,String,Number,Symbol在記憶體中占據固定大小,儲存在棧記憶體中
引用類型:Object,Array,Date,Function,RegExp等 引用類型的值是對象 儲存在堆記憶體中,棧記憶體存儲的是對象的變量辨別符以及對象在堆記憶體中的存儲位址。
基本類型的複制:其實就是建立了一個新的副本給将這個值指派給新變量, 改變值舊對象不會改變
引用類型的複制:其實就是複制了指針,這個最終都将指向同一個對象,改變其值新對象也會改變
注意:基本類型的比較 == 會進行類型轉換
淺拷貝
深拷貝
僅僅就是複制了引用,彼此操作不影響,slice() concat() object.assign
在堆中重新配置設定記憶體,不同的位址,相同的值,互不影響的 JSON.parse()将一個js對象序列化為一個json字元串JSON.stringify()将json字元串反序列化為一個js對象 es6的展開 {...}
重新在堆棧中建立記憶體,拷貝前後對象的基本類型互不影響。隻拷貝一層,不能對對象進行子對象進行拷貝
對對象中的子對象進行遞歸拷貝,拷貝前後兩個對象互不影響
6、setTimeout和setInterval的機制
因為js是單線程的。浏覽器遇到etTimeout和setInterval會先執行完目前的代碼塊,在此之前會把定時器推入浏覽器的待執行時間隊列裡面,等到浏覽器執行完目前代碼之後會看下事件隊列裡有沒有任務,有的話才執行定時器裡的代碼
7、前端跨域問題
同源政策(協定+端口号+域名要相同)
1、jsonp跨域(隻能解決get)
原理:動态建立一個script标簽。利用script标簽的src屬性不受同源政策限制,因為所有的src屬性和href屬性都不受同源政策的限制,可以請求第三方伺服器資源内容
步驟:1.去建立一個script标簽
2.script的src屬性設定接口位址
3.接口參數,必須要帶一個自定義函數名,要不然背景無法傳回資料
4.通過定義函數名去接受傳回的資料
2、document.domain 基礎域名相同 子域名不同
3、window.name 利用在一個浏覽器視窗内,載入所有的域名都是共享一個window.name
4、伺服器設定對CORS的支援
原理:伺服器設定Access-Control-Allow-Origin HTTP響應頭之後,浏覽器将會允許跨域請求
利用h5新特性window.postMessage()
iframe元素建立包含另外一個文檔的内聯架構(行内架構)(setTimeout進行異步加載)
解釋:浏覽器中的浏覽器!用于設定文本或者圖形的浮動圖文框或容器
它和跨域
1、document.domain 實作主域名相同,子域名不同的網頁通信
都設定為超域:document.domain = 'demo.com'
2、window.postMessageht(data, url),h5的API,啟動跨域通信
複制代碼8、圖檔預加載和懶加載
8.1、預加載:
提前加載圖檔,當使用者需要檢視是可以直接從本地緩存中渲染
為什麼要使用預加載:在網頁加載之前,對一些主要内容進行加載,以提供使用者更好的體驗,減少等待時間。否則,如果一個頁面的内容過于龐大,會出現留白。
解決頁面留白的方案:
1.預加載
2.使用svg站位圖檔,将一些結構快速搭建起來,等待請求的資料來了之後,替換目前的占位符
實作預加載的方法:
1.使用html标簽
2.使用Image對象
3.使用XMLHTTPRequest對像,但會精細控制預加載過程
8.2、懶加載(lazyload)
用戶端優化,減少請求數和延遲請求數,提升使用者體驗,減少無效資源的加載,防止并發加載的資源過多會阻塞js的加載,影響網站的正常使用
原理:首先将頁面上的圖檔的src屬性設定為空字元串,而圖檔的真是路經則設定帶data-original屬性中,當頁面滾動的時候需要去監聽scroll事件,在scroll事件的回調中,判斷我們的懶加載的圖檔是否進入到可視區域,如果圖檔在可視區域将圖檔的src屬性設定為data-original的值,這樣就可以實作延遲加載。
9、函數節流和防抖
防抖
節流
短時間内多次觸發同一個事件,隻執行最後一次,或者在開始時執行,中間不執行。比如公共汽車上車,要等待最後一個乘客上車
節流是連續觸發事件的過程中以一定時間間隔執行函數。節流會稀釋你的執行頻率,比如每間隔1秒鐘,隻會執行一次函數,無論這1秒鐘内觸發了多少次事件
都為解決高頻事件而來, scroll mousewhell mousemover touchmove onresize,後面有相應的代碼實作函數的節流和防抖。
10、js垃圾回收機制
1.JS具有自動垃圾收集的機制
2.JS的記憶體生命周期(變量的生命)
1.配置設定你所需要的空間 var a = 20
2.使用配置設定帶的記憶體(讀寫) alert(a + 10)
3.不适用的時候,釋放記憶體空間 a = null
3.JS的垃圾收集器每隔固定的時間就執行一次釋放操作,通用的是通過标記清除的算法
4.在局部作用域中,垃圾回收器很容易做出判斷并回收,全局比較難,是以應避免全局變量
标記清除算法:js最常見的垃圾回收方式,當變量進入執行環境的時候,比如函數中聲明一個變量,垃圾回收器将他标記為'進入環境',
當變量離開(函數執行完後),就其标記為'離開環境'。垃圾回收器會在運作的時候給存儲在記憶體中的所有變量加上标記,
然後去掉環境中的變量以及被環境中該變量所引用的變量(閉包)。在這些完成之後仍存在标記的就是要删除的變量了
11、一些檢驗方法
千萬不要使用typeof來判斷對象和數組,因為這種類型都會傳回object。
typeOf()是判斷基本類型的Boolean,Number,symbol, undefined, String。
對于引用類型:除function,都傳回object null傳回object。
installOf() 用來判斷A是否是B的執行個體,installof檢查的是原型。
toString() 是Object的原型方法,對于 Object 對象,直接調用 toString() 就能傳回 [Object Object] 。而對于其他對象,則需要通過 call / apply 來調用才能傳回正确的類型資訊。
hasOwnProperty()方法傳回一個布爾值,訓示對象自身屬性中是否具有指定的屬性,該方法會忽略掉那些從原型鍊上繼承到的屬性。
isProperty()方法測試一個對象是否存在另一個對象的原型鍊上。
valueof:所有對象都有valueof,如果存在任意原始值,他就預設将對象轉化為表示它的原始值。如果對象是複合值,而卻大部分對象無法真正表示一個原始值,是以預設的valueof()方法簡單的傳回對象本身,而不是傳回原始值
12、splice和slice、map和forEach、 filter()、reduce()的差別
1.slice(start,end):方法可以從已有數組中傳回標明的元素,傳回一個新數組,包含從start到end(不包含該元素)的數組方法
注意:該方法不會更新原數組,而是傳回一個子數組
2.splice():該方法想或者從數組中添加或删除項目,傳回被删除的項目。(該方法會改變原數組)
splice(index, howmany,item1,...itemx)
·index參數:必須,整數規定添加或删除的位置,使用負數,從數組尾部規定位置
·howmany參數:必須,要删除的數量,
·item1..itemx:可選,向數組添加新項目
3.map():會傳回一個全新的數組。使用于改變資料值的時候。會配置設定記憶體存儲空間數組并傳回,forEach()不會傳回資料
4.forEach(): 不會傳回任何有價值的東西,并且不打算改變資料,單純的隻是想用資料做一些事情,他允許callback更改原始數組的元素
5.reduce(): 方法接收一個函數作為累加器,數組中的每一個值(從左到右)開始縮減,最終計算一個值,不會改變原數組的值
6.filter(): 方法建立一個新數組,新數組中的元素是通過檢查指定數組中符合條件的所有元素。它裡面通過function去做處理
13、js\css阻塞
js阻塞
css阻塞
所有浏覽器在下載下傳JS的時候,會阻止一切其他活動,比如其他資源的下載下傳,内容的呈現等等。直到JS下載下傳、解析、執行完畢後才開始繼續并行下載下傳其他資源并呈現内容。為了提高使用者體驗,新一代浏覽器都支援并行下載下傳JS,但是JS下載下傳仍然會阻塞其它資源的下載下傳(例如.圖檔,css檔案等)。
因為浏覽器會維持html中css和js的順序,樣式表必須在嵌入的JS執行前先加載、解析完。而嵌入的JS會阻塞後面的資源加載,是以就會出現上面CSS阻塞下載下傳的情況。
14、類的建立和繼承
(es6)中class, extends
14.1、 繼承:
原型鍊繼承: function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; 無法實作多繼承
構造繼承:使用父類的構造函數來增強子類執行個體。function Cat(name){Animal.call(this);this.name = name || 'Tom';} 無法繼承父類原型鍊上的屬性跟方法 installof去檢驗
執行個體繼承:為父類執行個體添加新特性,作為子類執行個體的傳回
拷貝繼承:拷貝父類元素上的屬性跟方法
組合繼承:構造繼承 + 原型繼承的組合體
寄生組合繼承:通過寄生方式,在構造繼承上加一個Super函數(沒有執行個體和方法) 讓他的原型鍊指向父類的原型鍊 砍掉父類的執行個體屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次執行個體方法/屬性
14.2 給兩個構造函數A和B,如何實作A繼承B (Object.prototype)
function A(....){} A.prototype...
function B(....){} B.prototype...
A.prototype = Object.create(B.prototype) 再A的構造函數裡new B(props)
使用new一個函數的話,函數裡的構造函數的參數就為undefined,裡面的一些函數可能執行錯誤,因為this改變了
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
15、閉包和原型
15.1、閉包的了解
1、内部函數可以通路定義他們外部函數的參數和變量。(作用域鍊的向上查找,把外圍的作用域中的變量值存儲在記憶體中而不是在函數調用完畢後銷毀)設計私有的方法和變量,避免全局變量的污染
2、函數嵌套函數
3、本質是将函數内部和外部連接配接起來。優點是可以讀取函數内部的變量,讓這些變量的值始終儲存在記憶體中,不會在函數被調用之後自動清除
15.2、閉包的缺陷:
1.閉包的缺點就是常駐記憶體會增大記憶體使用量,并且使用不當容易造成記憶體洩漏
2.如果不是因為某些特殊任務而需要閉包,在沒有必要的情況下,在其它函數中建立函數是不明智的,因為閉包對腳本性能具有負面影響,包括處理速度和記憶體消耗。
15.3、記憶體的了解
記憶體溢出和記憶體洩漏(給的不夠用| 用了不歸還)
1、記憶體溢出:在程式中申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是記憶體溢出
2、記憶體洩漏:在程式申請記憶體後,無法釋放已申請的記憶體空間,一次記憶體洩漏危害可以忽略,但記憶體洩漏堆積後果很嚴重,無論多少記憶體,遲到會被占光
舉列子:閉包中的this,對象函數。匿名函數傳回函數return function
15.4、作用域
作用域:(由目前環境與上層環境一系列的變量對象組成!!!保證當先執行環境裡,有權通路的變量和函數是有序的,作用域鍊變量隻能被向上通路)
定義:由目前環境與上層環境的一系列變量對象組成(函數嵌套函數,内部一級級往上有序通路變量或對象)
作用是:保證目前執行環境裡,有權通路的變量和函數時有序的,作用域鍊的變量隻能被向上通路
變量通路到window對象及被終止,作用域鍊向下通路是不允許的
1.改變作用域有 with try..中的catch,
2.所有為定義的直接指派的變量自動聲明為全局作用域
作用域:一套規則,管理引擎如何在目前作用域以及嵌套的子作用域中根據辨別符名稱
查找變量(辨別符就是變量或者函數名)(隻用全局作用域和局部作用域)(作用域在它建立的時候就存在了)
代碼執行分為兩個階段:
1.代碼編譯階段:有編譯器完成,将代碼翻譯可執行的代碼,這個階段會被确定
2.代碼執行階段:有js引擎完成,主要執行可執行的大媽,這個階段執行上下文被建立(對象被建立)
執行上下文:一個看不見得對象,存在若幹個屬性和變量,它被調用的時候建立的。函數被調用檢視的this指向的object,object就是上下文(隻有被調用的時候建立)
15.5、作用域鍊參考連結
· 當代碼在一個環境中執行時,會建立變量對象的一個作用域鍊,
舉例子:var name ="Tom"
function sayHi () {
alert('Hi,'+name)
sayHi() //Hi, Tom
函數sayHi()的執行環境為全局環境,是以它的變量對象為window。當函數執行到name時,先查找局部環境,找到則換回,否則順着作用域查找,在全局環境中,
找到name傳回,這一查找變量的有序過程的依據就是作用域。
· 作用域鍊是保證執行環境有權通路的所有變量和函數的有序通路
15.6、原型鍊
原型鍊:函數的原型鍊對象constructor預設指向函數本身,原型對象除了有原型屬性外,為了實作繼承,還有一個原型鍊指針proto,該指針是指向上一層的原型對象,而上一層的原型對象的結構依然類似。是以可以利用_proto_一直指向Object的原型對象上,而Object原型對象用Object.prototype.proto=null表示原型鍊頂端。如此形成了js的原型鍊繼承。同時所有的js對象都有Object的基本防範
四、伺服器端面試篇
1、狀态碼
2XX(成功處理了請求狀态)
200 伺服器已經成功處理請求,并提供了請求的網頁
201 使用者建立或修改資料成功
202 一個請求已經進入背景
204 使用者删除成功
3XX(每次請求使用的重定向不要超過5次)
304 網頁上次請求沒有更新,節省帶寬和開銷
4XX(表示請求可能出錯,妨礙了伺服器的處理)
400 伺服器不了解請求的文法
401 使用者沒有權限(使用者名,密碼輸入錯誤)
403 使用者得到授權(401相反),但是通路被禁止
404 伺服器找不到請求的網頁,
5XX(表示伺服器在處理請求的時候發生内部錯誤)
500 伺服器遇到錯誤,無法完成請求
503 伺服器目前無法使用(超載或停機維護)
複制代碼2、304的緩存原理(添加Etag标簽.last-modified)
1.伺服器首先産生Etag,伺服器可在稍後使用它來判斷頁面是否被修改。本質上,用戶端通過該記号傳回伺服器要求伺服器驗證(用戶端)緩存)
2.304是HTTP的狀态碼,伺服器用來辨別這個檔案沒有被修改,不傳回内容,浏覽器接受到這個狀态碼會去去找浏覽器緩存的檔案
3.流程:用戶端請求一個頁面A。伺服器傳回頁面A,并在A上加一個Tage客服端渲染該頁面,并把Tage也存儲在緩存中。用戶端再次請求頁面A并将上次請求的資源和ETage一起傳遞給伺服器。伺服器檢查Tage.并且判斷出該頁面自上次用戶端請求之後未被修改。直接傳回304
last-modified: 客服端請求資源,同時有一個last-modified的屬性标記此檔案在伺服器最後修改的時間,客服端第二次請求此url時,根據http協定。浏覽器會向伺服器發送一個If-Modified-Since報頭,詢問該事件之後檔案是否被修改,沒修改傳回304
有了Last-Modified,為什麼還要用ETag?
1、因為如果在一秒鐘之内對一個檔案進行兩次更改,Last-Modified就會不正确(Last—Modified不能識别秒機關的修改)
2、某些伺服器不能精确的得到檔案的最後修改時間
3、一些檔案也行會周期新的更改,但是他的内容并不改變(僅僅改變修改的事件),這個時候我們并不希望用戶端認為檔案被修改,而重新Get
ETag,為什麼還要用Last-Modified?
1、兩者互補,ETag的判斷的缺陷,比如一些圖檔等靜态檔案的修改
2、如果每次掃描内容都生成ETag比較,顯然要比直接比較修改時間慢的多。
ETag是被請求變量的實體值(檔案的索引節,大小和最後修改的時間的Hash值)
1、ETag的值伺服器端對檔案的索引節,大小和最後的修改的事件進行Hash後得到的。
3、get/post的差別
1.get資料是存放在url之後,以?分割url和傳輸資料,參數之間以&相連; post方法是把送出的資料放在http包的Body中
2.get送出的資料大小有限制,(因為浏覽器對url的長度有限制),post的方法送出的資料沒有限制
3.get需要request.queryString來擷取變量的值,而post方式通過request.from來擷取變量的值
4.get的方法送出資料,會帶來安全問題,比如登入一個頁面,通過get的方式送出資料,使用者名和密碼就會出現在url上
4、http和https的總結
4.1、http協定的了解
1.超文本的傳輸協定,是用于從網際網路伺服器超文本傳輸到本地資源的傳輸協定
2.基于TCP/IP通信協定來傳遞資料(HTML,圖檔資源)
3.基于運用層的面向對象的協定,由于其簡潔、快速的方法、适用于分布式超媒體資訊系統
4.http請求資訊request:
請求行(request line)、請求頭部(header),空行和請求資料四部分構成
請求行,用來說明請求類型,要通路的資源以及所使用的HTTP版本.
請求頭部,用來說明伺服器要使用的附加資訊
空行,請求頭部後面的空行是必須的
請求資料也叫主體,可以添加任意的其他資料。
5.http相應資訊Response
狀态行、消息報頭、空行和響應正文
狀态行,由HTTP協定版本号, 狀态碼, 狀态消息 三部分組成
消息報頭,用來說明用戶端要使用的一些附加資訊
空行,消息報頭後面的空行是必須的
響應正文,伺服器傳回給用戶端的文本資訊。
4.2、http和https的差別
http
https
是以安全為目标的HTTP通道,簡單講是HTTP的安全版本,通過SSL加密
超文本傳輸協定。是一個客服端和伺服器端請求和應答的标準(tcp),使浏覽器更加高效,使網絡傳輸減少
4.3、http1.0、1.1、2.0的差別
1.0跟1.1的差別:
長連接配接:HTTP1.0需要使用keep-alive參數來告知伺服器建立一個長連接配接,而HTP1.1預設支援長連接配接
節約寬帶:HTTP1.1支援隻發送一個header資訊(不帶任何body資訊)
host域(設定虛拟站點,也就是說,webserver上的多個虛拟站點可以共享同一個ip端口):HTTP1.0沒有host域
1.1跟2.0的差別:
1.http2采用的二進制文本傳輸資料,而非http1文本格式,二進制在協定的解析和擴充更好
2.資料壓縮:對資訊頭采用了HPACK進行壓縮傳輸,節省了資訊頭帶來的網絡流量
3.多路複用:一個連接配接可以并發處理多個請求
4.伺服器推送:我們對支援HTTP2.0的webserver請求資料的時候,伺服器會順便把一些用戶端需要的資源一起推送到用戶端,免得用戶端再次建立連接配接發送請求到伺服器端擷取。這種方式非常合适加載靜态資源
5、web總結
5.1、web緩存
1.web緩存就是存在于用戶端與伺服器之間的一個副本、當你第一個送出請求後,緩存根據請求儲存輸出内容的副本
2.緩存的好處
(1)減少不必要的請求
(2)降低伺服器的壓力,減少伺服器的消耗
(3)降低網絡延遲,加快頁面打開速度(直接讀取浏覽器的數)
複制代碼5.2、常見的web安全及防護原理
1.sql注入原理:通郭sql指令插入到web表單遞交或者輸入活命,達到欺騙伺服器執行的惡意sql指令
防範:1.對使用者輸入進行校驗
2.不适用動态拼接sql
2.XSS(跨站腳本×××):往web頁面插入惡意的html标簽或者js代碼。
舉例子:在論壇放置一個看是安全的連結,竊取cookie中的使用者資訊
防範:1.盡量采用post而不使用get送出表單
2.避免cookie中洩漏使用者的隐式
3.CSRF(跨站請求僞裝):通過僞裝來自受信任使用者的請求
舉例子:黃轶老師的webapp音樂請求資料就是利用CSRF跨站請求僞裝來擷取QQ音樂的資料
防範:在客服端頁面增加僞随機數,通過驗證碼
XSS和CSRF的差別:
1.XSS是擷取資訊,不需要提前知道其他使用者頁面的代碼和資料包
2.CSRF代替使用者完成指定的動作,需要知道其他頁面的代碼和資料包
5.3、CDN(内容分發網絡)
1.盡可能的避開網際網路有可能影響資料傳輸速度和穩定性的瓶頸和環節。使内容傳輸的更快更穩定。
2.關鍵技術:内容存儲和分發技術中
3.基本原理:廣泛采用各種緩存伺服器,将這些緩存伺服器分布到使用者通路相對的地區或者網絡中。當使用者通路網絡時利用全局負載技術
将使用者的通路指向距離最近的緩存伺服器,由緩存伺服器直接相應使用者的請求(全局負載技術)
6、前端呈現流程(TCP三向交握,DOM樹渲染)
6.1、從輸入url到擷取頁面的完整過程 參考連結
1.查詢NDS(域名解析),擷取域名對應的IP位址 查詢浏覽器緩存
2.浏覽器與伺服器建立tcp連結(三次握手)
3.浏覽器向伺服器發送http請求(請求和傳輸資料)
4.伺服器接受到這個請求後,根據路經參數,經過後端的一些處理生成html代碼傳回給浏覽器
5.浏覽器拿到完整的html頁面代碼開始解析和渲染,如果遇到外部的css或者js,圖檔一樣的步驟
6.浏覽器根據拿到的資源對頁面進行渲染,把一個完整的頁面呈現出來
6.2、TCP三向交握
客服端發c起請求連接配接伺服器端s确認,伺服器端也發起連接配接确認客服端确認。
第一次握手:客服端發送一個請求連接配接,伺服器端隻能确認自己可以接受客服端發送的封包段
第二次握手: 服務端向客服端發送一個連結,确認客服端收到自己發送的封包段
第三次握手: 伺服器端确認客服端收到了自己發送的封包段
6.3、浏覽器渲染原理及流程 DOM -> CSSOM -> render -> layout -> print
流程:解析html以及建構dom樹 -> 建構render樹 -> 布局render樹 -> 繪制render樹
概念:1.建構DOM樹: 渲染引擎解析HTML文檔,首先将标簽轉換成DOM樹中的DOM node(包括js生成的标簽)生成内容樹
2.建構渲染樹: 解析對應的css樣式檔案資訊(包括js生成的樣式和外部的css)
3.布局渲染樹:從根節點遞歸調用,計算每一個元素的大小,位置等。給出每個節點所在的螢幕的精準位置
4.繪制渲染樹:周遊渲染樹,使用UI後端層來繪制每一個節點
重繪:當盒子的位置、大小以及其他屬性,例如顔色、字型大小等到确定下來之後,浏覽器便把這些顔色都按照各自的特性繪制一遍,将内容呈現在頁面上
觸發重繪的條件:改變元素外觀屬性。如:color,background-color等
重繪是指一個元素外觀的改變所觸發的浏覽器行為,浏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀
注意:table及其内部元素需要多次計算才能确定好其在渲染樹中節點的屬性值,比同等元素要多發時間,要盡量避免使用table布局
重排(重構/回流/reflow): 當渲染書中的一部分(或全部)因為元素的規模尺寸,布局,隐藏等改變而需要重新建構,這就是回流。
每個頁面都需要一次回流,就是頁面第一次渲染的時候
重排一定會影響重繪,但是重繪不一定會影響重排
複制代碼7、前端儲存總結
7.1、存儲方式與傳輸方式
1.indexBD: 是h5的本地存儲庫,把一些資料存儲到浏覽器中,沒網絡,浏覽器可以從這裡讀取資料,離線運用。5m
2.Cookie: 通過浏覽器記錄資訊确認使用者身份,最大4kb,這也就限制了傳輸的資料,請求的性能會受到影響
3.Session: 伺服器端使用的一種記錄客戶狀态的機制(session_id存在set_cookie發送到客服端,儲存為cookie)
4.localStroage: h5的本地存儲,資料永久儲存在客服端
1、cookie,sessionStorage,localStorage是存放在用戶端,session對象資料是存放在伺服器上
實際上浏覽器和伺服器之間僅需傳遞session id即可,伺服器根據session-id找到對應的使用者session對象
session存儲資料更安全一些,一般存放使用者資訊,浏覽器隻适合存儲一般的資料
2、cookie資料始終在同源的http請求中攜帶,在浏覽器和伺服器來回傳遞,裡面存放着session-id
sessionStorage,localStorage僅在本地儲存
3、大小限制差別,cookie資料不超過4kb,localStorage在谷歌浏覽中2.6MB
4、資料有效期不同,cookie在設定的(伺服器設定)有效期内有效,不管視窗和浏覽器關閉
sessionStorage僅在目前浏覽器視窗關閉前有效,關閉即銷毀(臨時存儲)
localStorage始終有效
複制代碼7.2、SessionStorage和localStorage差別:
1.sessionStorage用于本地存儲一個會話(session)中的資料,這些資料隻有在用一個會話的頁面中才能被通路(也就是說在第一次通信過程中)
并且在會話結束後資料也随之銷毀,不是一個持久的本地存儲,會話級别的儲存
2.localStorage用于持久化的本地存儲,除非主動删除資料,否則不會過期
7.3、token、cookie、session三者的了解
1、token就是令牌,比如你授權(登入)一個程式時,他就是個依據,判斷你是否已經授權該軟體(最好的身份認證,安全性好,且是唯一的)使用者身份的驗證方式
2、cookie是寫在用戶端一個txt檔案,裡面包括登入資訊之類的,這樣你下次在登入某個網站,就會自動調用cookie自動登入使用者名伺服器生成,發送到浏覽器、浏覽器儲存,下次請求再次發送給伺服器(存放着登入資訊)
3、session是一類用來用戶端和伺服器之間儲存狀态的解決方案,會話完成被銷毀(代表的就是伺服器和用戶端的一次會話過程)cookie中存放着sessionID,請求會發送這個id。sesion因為request對象而産生。