1. var的變量提升的底層原理是什麼?
JS引擎的工作方式是:
1) 先解析代碼,擷取所有被聲明的變量;
2)然後在運作。
也就是說分為預處理和執行兩個階段。
變量提升:
所有變量的聲明語句都會被提升到代碼頭部。
但是變量提升隻對var指令聲明的變量有效,
如果一個變量不是用var指令聲明的,
就不會發生變量提升。
js裡的function也可看做變量,
也存在變量提升情況。
2. JS如何計算浏覽器的渲染時間?
浏覽器的渲染過程主要包括以下幾步:
1) 解析HTML生成DOM樹。
2) 解析CSS生成CSSOM規則樹。
3) 将DOM樹與CSSOM規則樹合并在一起生成渲染樹。
4) 周遊渲染樹開始布局,
計算每個節點的位置大小資訊。
5) 将渲染樹每個節點繪制到螢幕。
優化考慮:
CSS 優先:
引入順序上,CSS 資源先于 JavaScript 資源。
JS置後:
通常把JS代碼放到頁面底部,
且JavaScript 應盡量少影響 DOM 的建構。
3. JS的回收機制?
垃圾回收機制是為了以防記憶體洩漏,
(記憶體洩漏: 當已經不需要某塊記憶體時這塊記憶體還存在着),
垃圾回收機制就是間歇的不定期的
尋找到不再使用的變量,
并釋放掉它們所指向的記憶體。
JS有兩種變量:
全局變量和在函數中産生的局部變量。
局部變量的生命周期在函數執行過後就結束了,
此時便可将它引用的記憶體釋放(即垃圾回收),
但全局變量生命周期會持續到浏覽器關閉頁面。
JS執行環境中的垃圾回收器有兩種方式:
标記清除(mark and sweep)
、引用計數(reference counting)。
标記清除:
垃圾收集器給記憶體中的所有變量都加上标記,
然後去掉環境中的變量以及被環境中的變量引用的變量的标記。
在此之後再被加上的标記的變量即為需要回收的變量,
因為環境中的變量已經無法通路到這些變量。
引用計數(reference counting):
這種方式常常會引起記憶體洩漏,
低版本的IE使用這種方式。
機制就是跟蹤一個值的引用次數,
當聲明一個變量
并将一個引用類型指派給該變量時該值引用次數加1,
當這個變量指向其他一個時該值的引用次數便減一。
當該值引用次數為0時就會被回收。
4. 垂直水準居中的方式?
方式一: 定位
父元素設定為:position: relative;
子元素設定為:position: absolute;
距上50%,據左50%,
然後減去元素自身寬度的距離就可以實作
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. 實作一個三欄布局,中間版塊自适應方法有哪些?
浮動和定位
浮動方式:
<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設定為relative,
兩個邊欄的position設定成absolute。
6. 如何判斷一個對象是否為數組?
撩課小編:
1) isPrototypeOf()方法,
判定Array是不是在obj的原型鍊中,
如果是,
則傳回true,否則false;
2) obj instanceof Array;
3) Object.prototype.toString.call(obj);
4) Array.isArray(obj); // 不推薦
7. 行内元素和塊級元素有哪些? img屬于什麼元素?
塊元素(block element)
* address - 位址
* blockquote - 塊引用
* center - 舉中對齊塊
* dir - 目錄清單
* div - 常用塊級容易,也是css layout的主要标簽
* dl - 定義清單
* fieldset - form控制組
* form - 互動表單
* h1 - 大标題
* h2 - 副标題
* h3 - 3級标題
* h4 - 4級标題
* h5 - 5級标題
* h6 - 6級标題
* hr - 水準分隔線
* isindex - input prompt
* menu - 菜單清單
* noframes - frames可選内容,
(對于不支援frame的浏覽器顯示此區塊内容
* noscript - 可選腳本内容
(對于不支援script的浏覽器顯示此内容)
* ol - 排序表單
* p - 段落
* pre - 格式化文本
* table - 表格
* ul - 非排序清單
内聯元素(inline element)
* a - 錨點
* abbr - 縮寫
* acronym - 首字
* b - 粗體(不推薦)
* bdo - bidi override
* big - 大字型
* br - 換行
* cite - 引用
* code - 計算機代碼(在引用源碼的時候需要)
* dfn - 定義字段
* em - 強調
* font - 字型設定(不推薦)
* i - 斜體
* img - 圖檔
* input - 輸入框
* kbd - 定義鍵盤文本
* label - 表格标簽
* q - 短引用
* s - 中劃線(不推薦)
* samp - 定義範例計算機代碼
* select - 項目選擇
* small - 小字型文本
* span - 常用内聯容器,定義文本内區塊
* strike - 中劃線
* strong - 粗體強調
* sub - 下标
* sup - 上标
* textarea - 多行文本輸入框
* tt - 電傳文本
* u - 下劃線
* var - 定義變量
可變元素
可變元素為根據上下文語境
決定該元素為塊元素或者内聯元素。
* applet - java applet
* button - 按鈕
* del - 删除文本
* iframe - inline frame
* ins - 插入的文本
* map - 圖檔區塊(map)
* object - object對象
* script - 用戶端腳本
8. margin坍塌?
撩課小編: 當兩個盒子在垂直方向上設定margin值時,會出現塌陷現象。
解決方案:
-
給父盒子添加border
2.給父盒子添加padding-top
3.給父盒子添加overflow:hidden
4.父盒子:position:fixed
5.父盒子:display:table
6.給子元素的前面添加一個兄弟元素 屬性為:content:""; overflow:hidden;
9. 說說BFC原理?
撩課小編:
BFC就是頁面上的一個隔離的獨立容器,
容器裡面的子元素不會影響到外面的元素。
因為BFC内部的元素和外部的元素絕對不會互相影響,
是以,
當BFC外部存在浮動時,
它不會影響BFC内部Box的布局,
BFC會通過變窄,
而不與浮動有重疊。
同樣的,當BFC内部有浮動時,
為了不影響外部元素的布局,
BFC計算高度時會包括浮動的高度。
避免margin重疊也是這樣的一個道理。
10. 寫一下節點增删改?
// 注意:動态建立元素不會直接顯示在頁面當中,
// 前面必須是document,不能是其他
(1)document.createElement(标簽名);
// 在指定父級子節點最後一個後面追加子元素
(2)父級.appendChild(要追加的元素) ;
// 在父級的指定子元素前面插入一個新元素
//(注意:先判斷如果第二個參數的節點是否存在)
(3)父級.insertBefore(新的元素,指定的已有子元素);
// 深克隆
//(負值标簽、标簽屬性、标簽裡面内容 淺克隆
//(負值标簽、标簽屬性不複制标簽裡面内容)
(4)元素.cloneNode(true) 或者元素.cloneNode(false)
(5)父級.removeChild(已有子元素);
(6)父級.replaceChild(新的元素節點,原有元素節點);
11. 如何擷取元素的父節點和兄弟節點,寫一下?
擷取父節點:
// 1. parentNode擷取父節點
// 擷取的是目前元素的直接父元素。
var p = document.getElementById("test").parentNode;
// 2. parentElement擷取父節點
// parentElement和parentNode一樣,
//隻是parentElement是ie的标準。
var p1 =
document.getElementById("test").parentElement;
// 3. offsetParent擷取所有父節點
var p2 =
document.getElementById("test").offsetParent;
擷取兄弟節點:
// 1. 通過擷取父親節點再擷取子節點來擷取兄弟節點
var brother1 =
document.getElementById("test").parentNode.children[1];
// 2.擷取上一個兄弟節點
//在擷取前一個兄弟節點的時候
//可以使用previousSibling和previousElementSibling。
//他們的差別是previousSibling會比對字元,
//包括換行和空格,而不是節點。
//previousElementSibling則直接比對節點。
var brother2 =
document.getElementById("test").previousElementSibling;
var brother3 =
document.getElementById("test").previousSibling;
// 3. 擷取下一個兄弟節點
var brother4 =
document.getElementById("test").nextElementSibling;
var brother5 =
document.getElementById("test").nextSibling;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM982Yfh3dmETP5pXYs9Fe3ZSN902byZGe3ZCciV2d9AHdmYWan1DdtZ2X4d3PwQjNvwVQshEMYplT55GTQJWa5UESUdkM4JFdHJHNjxWMilGdWNnTqZ3YpVFO2FWTiNlcqZFWyZHMDp0dvFlYpZHVXZTd2glN6B1TEF3T1lkdkdWbSdTZyM0cXNXYpRUSvw1ZuB3X6lmYt12Lc52YuMWawFnL6lmYt12Lc9CX6MHc0RHaiojIsJye.jpg)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM982Yfh3dmETP5pXYs9Fe3ZSN902byZGe3ZCciV2d9AHdmYWan1DdtZ2X4d3PwQjNvwVQshEMYplT55GTQJWa5UESUdkM4JFdHJHNjxWMilGdWNnTqZ3YpVFO2FWTiNlcqZFWyZHMDp0dvFlYpZHVXZTd2glN6B1TEF3T1lkdkdWbSdTZyM0cXNXYpRUSvw1ZuB3X6lmYt12Lc52YuMWawFnL6lmYt12Lc9CX6MHc0RHaiojIsJye.jpg)
12. 給你一個亂序數組,你怎麼排序?
sort, 冒泡, 選擇, 二分法....