JS基礎知識
1.CSS和JS在網頁中的放置順序是怎樣的?##
- 一般來說CSS放在頂部,JS放在底部加載
- css放在前端加載時因為頁面渲染時首先是根據DOM結構生成一個DOM樹,然后加上CSS樣式生成一個渲染書,如果CSS放在后面可能頁面會出現閃的感覺,或者是白屏,或者布局混亂樣式很丑直到CSS加載完成。
- JS會阻塞加載,會影響到頁面加載的速度,如果一個JS文件比較大,算法也比較復雜,會使得頁面加載速度變得很慢。
解釋白屏和FOUC##
瀏覽器的白屏與無樣式內容閃爍(FOUC),是由于瀏覽器加載與顯示頁面方式不同造成的:
解決方式:使用link標簽將樣式表放置在head標簽中。
IE————會出現白屏現象
原因是其等待頁面組件包括樣式表全部加載完成后才呈現整個頁面。若樣式表放在頁面底部,將會出現白屏。樣式表在頁面中位置并不影響頁面中組件的下載時間,但是會影響頁面的呈現。
如果樣式表仍在加載,構建呈現樹就是一種浪費,因為在所有樣式表加載并解釋完畢之前無需要繪制任何東西,否則,在其準備好之前顯示的內容會遇到FOUC問題。就好比IE不希望加載的時候頁面字體顏色一會從黑色變成紅色,一會沒有下邊框。一會又多出來個什么,IE瀏覽器會阻止頁面頁面的逐步呈現直至樣式表加載解析完畢,然后頁面所有的內容同時出現在屏幕上,就會出現白屏現象。不過貌似白屏用戶體驗度更差。
這樣IE 就避免了FOUC問題,也就自然的會出現白屏現象。在IE中,將樣式表放在文檔底部公導致白屏問題的情形有以下幾種:
一、在新窗口中打開時
二、重新加載時
三、作為主頁打開時
FireFox 當把樣式表放在頁面底部時,會遇到FOUC問題,因為FF為了用戶體驗,對所有都是對頁面中的組件逐步呈現。
無論是將樣式表置于頂部還是底部,FF總是采用逐步呈現的方式來加載組件。因此,若樣式表不是最初頁面呈現所必需的,則用戶用戶基本感覺不到有什么差別(當然加載時間是不一樣的,最后會稍微再補充一下);而當樣式表為頁面程序所必需的時候,則會出現無樣式內容閃爍現象。
另外IE瀏覽器和Firefox的區別
Firfox瀏覽器:樣式表位于頂部:頁面內容逐步呈現
樣式表位于底部:
與頁面呈現內容無關:頁面內容逐步呈現
呈現與頁面呈現內容有關:出現無樣式內容閃爍
IE瀏覽器
- 樣式表位于頂部:逐步加載
- 樣式表位于底部:
- 出現白屏:當重新加載頁面、將頁面設置為默認首頁并打開、在新窗口中打開頁面時出現
async和defer的作用是什么?有什么區別
-
<script src="script.js"></script>
沒有 defer 或async,瀏覽器會立即加載并執行指定的腳本,“立即”指的是在渲染該 script 標簽之下的文檔元素之前,也就是說不等待后續載入的文檔元素,讀到就加載并執行。 -
<script async src="script.js"></script>
有 async,加載和渲染后續文檔元素的過程將和 script.js 的加載與執行并行進行(異步)。 -
<script defer src="myscript.js"></script>
有 defer,加載后續文檔元素的過程將和 script.js 的加載并行進行(異步),但是 script.js 的執行要在所有元素解析完成之后,DOMContentLoaded事件觸發之前完成。然后從實用角度來說呢,首先把所有腳本都丟到 </body> 之前是最佳實踐,因為對于舊瀏覽器來說這是唯一的優化選擇,此法可保證非腳本的其他一切元素能夠以最快的速度得到加載和解析。
藍色線代表網絡讀取,紅色線代表執行時間,這倆都是針對腳本的;綠色線代表 HTML 解析。
此圖告訴我們以下幾個要點: - defer 和 async 在網絡讀?。ㄏ螺d)這塊兒是一樣的,都是異步的(相較于 HTML 解析)
- 它倆的差別在于腳本下載完之后何時執行,顯然 defer 是最接近我們對于應用腳本加載和執行的要求的
- 關于 defer,此圖未盡之處在于它是按照加載順序執行腳本的,這一點要善加利用
- async 則是一個亂序執行的主,反正對它來說腳本的加載和執行是緊緊挨著的,所以不管你聲明的順序如何,只要它加載完了就會立刻執行
- 仔細想想,async對于應用腳本的用處不大,因為它完全不考慮依賴(哪怕是最低級的順序執行),不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的,最典型的例子:Google Analytics
參考[defer和async的區別][2]
簡述網頁的渲染機制
渲染一個Web頁面,瀏覽器執行的所有步驟如下:
1.瀏覽器解析(包括HTML,SVG,XHTML,CSS,JavaScript等等)
解析HTML代碼,構建Document Object Model (DOM)
解析CSS代碼,構建CSS Object Model (CSSOM)
-
JavaSript通過API操作DOM和CSSOM, 構建渲染樹
構建過程如下
0_1458660207168_render-tree-construction.png 2.布局階段
在屏幕上繪制渲染樹中的所有節點的幾何屬性,比如: 位置,寬高,大小等等
3.繪制元素
繪制所有節點的可視屬性,比如:顏色,背景,邊框,背景圖等,這期間可能會產生多個圖層(堆疊上下文)。
4.合并渲染層
把以上繪制的所有圖層(類似于PhotoShop中的“圖層”)合并,最終輸出一張圖片。
JavaScript 定義了幾種數據類型? 哪些是簡單類型?哪些是復雜類型?
在JavaScript中,有5種基本數據類型和1種復雜數據類型,可以使用typeof
來檢測是什么數據類型。
基本數據類型:
- number數據類型 —— var num=123;
- string數據類型 —— var str="abcd";
- boolean數據類型 —— var bool=ture;
- 未定義undefined —— var a;
- 空 null —— var a=null
復雜數據類型:
- object —— var obj={"name":"小明","age":"14"};
簡單數據類型:
- number數據類型 —— var num=123;
- string數據類型 —— var str="abcd";
- boolean數據類型 —— var bool=ture;
特殊數據類型:
- 未定義undefined —— var a;
- 空 null —— var a=null
NaN、undefined、null分別代表什么?
- null表示"沒有對象"——即該處不應該有值。
- undefined表示"缺少值"——表明此處應該有一個值,但是沒有定義.例如
var a;
- NaN是一個特殊值,表示非數(not a Number)例如Number ("123a") 得到的即為NaN
NaN 不等于自己,
typeof和instanceof的作用和區別?
instanceof 和typeof都能用來判斷一個變量是否為空或是什么類型的變量。
- typeof 用以獲取一個變量的類型,typeof 一般只能返回如下幾個結果:number,boolean,string,function,object,undefined。
- 我們可以使用 typeof 來獲取一個變量是否存在,如 if(typeof a!="undefined"){},而不要去使用 if(a) 因為如果 a 不存在(未聲明)則會出錯,對于 Array,Null 等特殊對象使用 typeof 一律返回 object。
這正是 typeof 的局限性。如果我們希望獲取一個對象是否是數組,或判斷某個變量是否是某個對象的實例則要選擇使用instanceof。 - instanceof 用于判斷一個變量是否某個對象的實例,如 var a=new Array();alert(a instanceof Array);會返回 true,
- 同時 alert(a instanceof Object) 也會返回 true;這是因為 Array 是 object 的子類。再如:function test(){};var a=new test();alert(a instanceof test) 會返回 true。
談到instanceof 我們要多插入一個問題,就是 function 的 arguments,我們大家也許都認為 arguments 是一個 Array,但如果使用 instaceof 去測試會發現 arguments 不是一個 Array 對象,盡管看起來很像。
代碼
1.完成如下代碼判斷一個變量是否是數字、字符串、布爾、函數
function isNumber(el){
return typeof el==="number";
}
function isString(el){
return typeof el==="string";
}
function isBoolean(el){
return typeof el==="boolean";
}
function isFunction(el){
return typeof el==="function";
}
var a = 2,
b = "jirengu",
c = false;
alert( isNumber(a) ); //true
alert( isString(a) ); //false
alert( isString(b) ); //true
alert( isBoolean(c) ); //true
alert( isFunction(a)); //false
alert( isFunction( isNumber ) ); //true
2以下代碼的輸出結果是?(難度**)
console.log(1+1); //2 number
console.log("2"+"4"); //24 string
console.log(2+"4"); //24 string
console.log(+new Date());//1458661115766 number
console.log(+"4");//4 string
3.以下代碼的輸出結果是? (難度***)
var a = 1;
a+++a;//輸出結果為3
typeof a+2;//輸出結果為number2
4.遍歷數組,把數組里的打印數組每一項的平方 (難度**)
var arr = [3,4,5]
for(var i=0;i<arr.length;i++){
console.log(arr[i]*arr[i]);
}
// todo..
// 輸出 9, 16, 25
5.遍歷 JSON, 打印里面的值 (難度**)
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for(vari in obj){
console.log(i+":"+obj[i]+";")
}
6.下面代碼的輸出是? 為什么
console.log(a);//undefined
var a = 1;
console.log(a);//1
console.log(b);//報錯,因為變量b未定義。
第一個顯示為undefinde 是因為JS的變量提升。相當于
var a;
console.log(a);
var a = 1;
console.log(a);
console.log(b);
變量提升,就是把變量提升提到函數的top的地方。我么需要說明的是,變量提升 只是提升變量的聲明,并不會把賦值也提升上來。
@hunger