1. var的變量提升的底層原理是什么?
JS引擎的工作方式是:
1) 先解析代碼右莱,獲取所有被聲明的變量;
2) 然后在運行叶洞。也就是說分為預(yù)處理和執(zhí)行兩個階段围段。
補充:
變量提升:所有變量的聲明語句都會被提升到代碼頭部婚惫。
但是變量提升只對var命令聲明的變量有效娩脾,如果一個變量不是
用var命令聲明的知市,就不會發(fā)生變量提升。
js里的function也可看做變量活孩,也存在變量提升情況物遇。
2. JS如何計算瀏覽器的渲染時間?
瀏覽器的渲染過程主要包括以下幾步:
1) 解析HTML生成DOM樹。
2) 解析CSS生成CSSOM規(guī)則樹憾儒。
3) 將DOM樹與CSSOM規(guī)則樹合并在一起生成渲染樹询兴。
4) 遍歷渲染樹開始布局,計算每個節(jié)點的位置大小信息起趾。
5) 將渲染樹每個節(jié)點繪制到屏幕诗舰。
優(yōu)化考慮:
CSS 優(yōu)先:引入順序上,CSS 資源先于 JavaScript 資源训裆。
JS置后:通常把JS代碼放到頁面底部眶根,且JavaScript 應(yīng)盡量少影響 DOM 的構(gòu)建。
3. JS的回收機制?
垃圾回收機制就是間歇的不定期的尋找到不再使用的變量边琉,
并釋放掉它們所指向的內(nèi)存; 主要為了以防內(nèi)存泄漏属百,
(內(nèi)存泄漏: 當(dāng)已經(jīng)不需要某塊內(nèi)存時這塊內(nèi)存還存在著),
JS有兩種變量: 全局變量和在函數(shù)中產(chǎn)生的局部變量。
局部變量的生命周期在函數(shù)執(zhí)行過后就結(jié)束了变姨,
此時便可將它引用的內(nèi)存釋放(即垃圾回收);
但全局變量生命周期會持續(xù)到瀏覽器關(guān)閉頁面族扰。
JS執(zhí)行環(huán)境中的垃圾回收器有兩種方式:
標(biāo)記清除(mark and sweep)、
引用計數(shù)(reference counting)钳恕。
標(biāo)記清除: 垃圾收集器給內(nèi)存中的所有變量都加上標(biāo)記别伏,
然后去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記。
在此之后再被加上的標(biāo)記的變量即為需要回收的變量忧额,
因為環(huán)境中的變量已經(jīng)無法訪問到這些變量厘肮。
引用計數(shù)(reference counting): 這種方式常常會引起內(nèi)存泄漏,
低版本的IE使用這種方式睦番。機制就是跟蹤一個值的引用次數(shù)类茂,
當(dāng)聲明一個變量并將一個引用類型賦值給該變量時該值引用次數(shù)加1,
當(dāng)這個變量指向其他一個時該值的引用次數(shù)便減一托嚣。
當(dāng)該值引用次數(shù)為0時就會被回收巩检。
4. 垂直水平居中的方式?
/**
方式一: 定位
父元素設(shè)置為:position: relative;
子元素設(shè)置為:position: absolute;
距上50%,據(jù)左50%示启,然后減去元素自身寬度的距離就可以實現(xiàn)
*/
width: 100px;
height: 100px;
position: absolute;
left: 50%;
top: 50%;
margin: -50px 0 0 -50px;
/** 方式二: flex布局 */
display: flex; //flex布局
justify-content: center; // 使子項目水平居中
align-items: center; // 使子項目垂直居中
/** 方式三: table-cell (不推薦) */
display: table-cell;
vertical-align: middle;//使子元素垂直居中
text-align: center;//使子元素水平居中
5. 實現(xiàn)一個三欄布局兢哭,中間版塊自適應(yīng)方法有哪些?
// 方式一: 浮動和定位
<div class="content">
<div class="left">left</div>
<div class="right">right</div>
<div class="center">center</div>
</div>
.left{
float: left;
width: 100px;
height: 200px;
}
.right{
float: right;
padding: 0;
width: 100px;
height: 200px;
}
.center{
margin: 0 100px 0 200px;
}
方式二: 將父容器的position設(shè)置為relative,兩個邊欄的position設(shè)置成absolute夫嗓。
6. 如何判斷一個對象是否為數(shù)組?
1) isPrototypeOf()方法迟螺,判定Array是不是在obj的原型鏈中冲秽,如果是,則返回true,否則false;
2) obj instanceof Array;
3) Object.prototype.toString.call(obj)矩父;
4) Array.isArray(obj); // 不推薦
7. margin坍塌?
當(dāng)兩個盒子在垂直方向上設(shè)置margin值時锉桑,會出現(xiàn)塌陷現(xiàn)象。
解決方案主要包括:
1. 給父盒子添加border;
2. 給父盒子添加padding-top;
3. 給父盒子添加overflow:hidden;
4. 父盒子:position:fixed;
5. 父盒子:display:table;
6. 給子元素的前面添加一個兄弟元素
屬性為:content:"";
overflow:hidden;
8. 說說BFC原理?
BFC就是頁面上的一個隔離的獨立容器窍株,
容器里面的子元素不會影響到外面的元素民轴。
因為BFC內(nèi)部的元素和外部的元素絕對不會互相影響,
因此球订,當(dāng)BFC外部存在浮動時后裸,
它不會影響B(tài)FC內(nèi)部Box的布局,
BFC會通過變窄冒滩,而不與浮動有重疊轻抱。
同樣的,當(dāng)BFC內(nèi)部有浮動時旦部,
為了不影響外部元素的布局,
BFC計算高度時會包括浮動的高度较店。
避免margin重疊也是這樣的一個道理士八。
9. 寫一下節(jié)點增刪改?
// 注意:動態(tài)創(chuàng)建元素不會直接顯示在頁面當(dāng)中,
前面必須是document梁呈,不能是其他
(1)document.createElement(標(biāo)簽名);
// 在指定父級子節(jié)點最后一個后面追加子元素
(2)父級.appendChild(要追加的元素) ;
// 在父級的指定子元素前面插入一個新元素
(注意:先判斷如果第二個參數(shù)的節(jié)點是否存在)
(3)父級.insertBefore(新的元素婚度,指定的已有子元素);
// 深克隆(負值標(biāo)簽官卡、標(biāo)簽屬性蝗茁、標(biāo)簽里面內(nèi)容);
淺克隆(負值標(biāo)簽寻咒、標(biāo)簽屬性不復(fù)制標(biāo)簽里面內(nèi)容)
(4)元素.cloneNode(true) 或者元素.cloneNode(false);
(5)父級.removeChild(已有子元素);
(6)父級.replaceChild(新的元素節(jié)點哮翘,原有元素節(jié)點);
10. 如何獲取元素的父節(jié)點和兄弟節(jié)點,寫一下?
// 獲取父節(jié)點:
// 1. parentNode獲取父節(jié)點
// 獲取的是當(dāng)前元素的直接父元素毛秘。
var p = document.getElementById("test").parentNode;
// 2. parentElement獲取父節(jié)點
// parentElement和parentNode一樣饭寺,只是parentElement是ie的標(biāo)準(zhǔn)。
var p1 = document.getElementById("test").parentElement;
// 3. offsetParent獲取所有父節(jié)點
var p2 = document.getElementById("test").offsetParent;
獲取兄弟節(jié)點:
// 1. 通過獲取父親節(jié)點再獲取子節(jié)點來獲取兄弟節(jié)點
var brother1 = document.getElementById("test").parentNode.children[1];
// 2. 獲取上一個兄弟節(jié)點
// 在獲取前一個兄弟節(jié)點的時候可以使用previousSibling
// 和previousElementSibling叫挟。
// 他們的區(qū)別是previousSibling會匹配字符艰匙,
// 包括換行和空格,而不是節(jié)點抹恳。
// previousElementSibling則直接匹配節(jié)點员凝。
var brother2 = document.getElementById("test").previousElementSibling;
var brother3 = document.getElementById("test").previousSibling;
// 3. 獲取下一個兄弟節(jié)點
var brother4 = document.getElementById("test").nextElementSibling;
var brother5 = document.getElementById("test").nextSibling;
11. 給你一個亂序數(shù)組,你怎么排序?
撩課小編: sort, 冒泡, 選擇, 二分法....