1. CSS和JS在網(wǎng)頁中的放置順序是怎樣的俯画?
- css放在head標(biāo)簽里
- js放在body標(biāo)簽的最后
主要是為了避免白屏和FOUC,詳見問答2
2. 解釋白屏和FOUC
白屏與無樣式內(nèi)容閃爍(FOUC,Flash of Unstyled Content)是因為不同瀏覽器加載與顯示頁面的機制不同而造成的亮航。
- 當(dāng)把css樣式放在底部或者使用@import方式引入樣式時
一些瀏覽器例如chrome,他的加載和渲染機制是等css全部加載解析完后再渲染展示頁面,而這個等待的時間就為白屏祈争。 - 另一些瀏覽器例如Firefox,他會在css未加載前先展現(xiàn)頁面,等css加載后再重繪一次,這就造成了FOUC (無樣式內(nèi)容閃爍)穿扳。
- 當(dāng)<head>元素中包含JavaScript文件時
必須等到所有的JavaScript代碼都被下載,解析和執(zhí)行完成以后,才能開始呈現(xiàn)頁面的內(nèi)容(瀏覽器遇到<body>標(biāo)簽才開始呈現(xiàn)內(nèi)容).如果JavaScript代碼很多,這會導(dǎo)致頁面呈現(xiàn)延時,延時期間瀏覽器窗口將是一片空白.
所以為了避免這些問題,最好使用LINK標(biāo)簽將CSS樣式表放在<head>標(biāo)簽中,JavaScript引用放在<body>標(biāo)簽的末尾旨涝。
3. async和defer的作用是什么失都?有什么區(qū)別?
當(dāng)瀏覽器碰到 script 腳本的時候:
- defer是script標(biāo)簽中處理腳本運行的屬性之一立润,中文稱作延時,作用是js在頁面加載后才會運行腳本蟋滴,即同時加載js染厅,延時執(zhí)行js。語法規(guī)則為:
<script src="demo.js" defer="defer"></script>
- async(HTML5)是script標(biāo)簽中處理腳本運行的另一屬性津函,中文稱作異 步肖粮,作用是腳本會異步加載而不阻塞頁面加載,并且js一旦下載完畢就會立即執(zhí)行尔苦。
<script src="demo.js" async="async"></script>
關(guān)于二者的加載和執(zhí)行方式如下圖所示:
【注意】無論是defer還是async都僅適用于外部腳本
還有幾點要注意:
- defer腳本會在DOMContentLoaded和load事件之前執(zhí)行;如果有多個聲明了defer的腳本涩馆,則會按順序下載和執(zhí)行
- async會在load事件之前執(zhí)行行施,但并不能確保與DOMContentLoaded的執(zhí)行先后順序;如果有多個聲明了async的腳本,其下載和執(zhí)行也是異步的魂那,不能確保彼此的先后順序(誰先下載完先執(zhí)行)
- Js可以改變DOM樹,所以操作 DOM 的Js腳本不要使用 async和defer 如果一定要使用,需要把需要操作 DOM 的部分放在 DOMContentLoaded 事件回調(diào)中執(zhí)行
關(guān)于兼容性:
由CanIUSe可知,
async在IE<=9時不支持蛾号,其他瀏覽器OK
defer在IE<=9時部分支持,其他瀏覽器OK
所以有時會在async不支持的時候啟用defer涯雅,但defer在某些情況下還是有bug
<script async defer src="script.js"></script>
所謂部分支持是指瀏覽器盡管已經(jīng)支持 defer须教,但是沒有嚴(yán)格按照 HTML5 標(biāo)準(zhǔn)處理,這會導(dǎo)致bug斩芭,這個bug在這個Issue中有描述
這也是為什么《javascript高級程序設(shè)計》一書中寫過
“在現(xiàn)實當(dāng)中,延遲腳本并不一定會按照順序執(zhí)行乐疆,也不一定會在DOMContentLoaded事件觸發(fā)前執(zhí)行划乖,因此最好只包含一個延遲腳本”的原因
所以最保險的方法還是把JavaScrpipt引用放在<body>標(biāo)簽的末尾.
4. 簡述網(wǎng)頁的渲染機制
- 解析文檔并構(gòu)建樹:Html解析以構(gòu)建DOM Tree和Css解析以構(gòu)建Style Rules Tree
- 構(gòu)建渲染樹Render Tree:此時渲染引擎會將DOM Tree和Style Rules Tree結(jié)合在一起形成Render樹,它由一些包含有顏色和大小等屬性的矩形組成
- 布局Layout:Render樹構(gòu)建好了之后挤土,將會執(zhí)行布局過程琴庵,它將確定每個節(jié)點在屏幕上的確切坐標(biāo)。
-
繪制paint:再下一步就是繪制仰美,即遍歷render樹迷殿,并使用UI后端層繪制每個節(jié)點】г樱
5.JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是簡單類型?哪些是復(fù)雜類型庆寺?
ES5有五種數(shù)據(jù)類型:
- 數(shù)值(number):整數(shù)和小數(shù)(比如1和3.14)
- 字符串(string):字符組成的文本(比如”Hello World”)
- 布爾值(boolean):true(真)和false(假)兩個特定值
- undefined:表示“未定義”或不存在,即此處目前沒有任何值
- null:表示空缺诉字,即此處應(yīng)該有一個值懦尝,但目前為空
- 對象(object):各種值組成的集合 。object為復(fù)雜類型壤圃,其他為簡單類型陵霉。
通常,我們將數(shù)值伍绳、字符串踊挠、布爾值稱為原始類型(primitive type)的值,即它們是最基本的數(shù)據(jù)類型冲杀,不能再細(xì)分了效床。而將對象稱為合成類型(complex type)的值,因為一個對象往往是多個原始類型的值的合成漠趁,可以看作是一個存放各種值的容器扁凛。至于undefined和null,一般將它們看成兩個特殊值闯传。
【注】
1.數(shù)組和函數(shù)算是廣義的對象谨朝,null也屬于對象
2.NaN是一種特殊的數(shù)值
6. NaN卤妒、undefined、null分別代表什么?
- NaN:表示Not a Number字币,不是一種獨立的數(shù)據(jù)類型则披,而是一種特殊數(shù)值,它的數(shù)據(jù)類型依然屬于Number洗出,只不過數(shù)值計算時不符合計算法則
0/0//NaNMath.sqrt(-5)//NaN - null 是一個表示"無"的對象士复,轉(zhuǎn)為數(shù)值時為0;
- undefined是一個表示"無"的原始值翩活,轉(zhuǎn)為數(shù)值時為NaN阱洪。
[注意]
設(shè)置一個值為 null 是合理的,如objA.valueA = null;但設(shè)置一個值為 undefined 是不合理的
7. typeof和instanceof的作用和區(qū)別?
- typeof是返回一個字符串并顯示為參數(shù)數(shù)據(jù)類型的運算符菠镇,但它無法區(qū)分?jǐn)?shù)據(jù)類型object究竟是出自狹義的對象object還是數(shù)組
示例如下:
typeof 37 === 'number';
typeof "bla" === 'string';
typeof true === 'boolean';
typeof Symbol('foo') === 'symbol';
typeof undefined === 'undefined';
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object';
typeof function(){} === 'function';
- instanceof運算符可以用來判斷某個構(gòu)造函數(shù)的prototype屬性所指向的對象是否存在于另外一個要檢測對象的原型鏈上冗荸,簡單的講就是判斷一個變量是否是某個對象(類)的實例,返回值是布爾類型的利耍。
function C(){} //構(gòu)造函數(shù)
function D(){} //構(gòu)造函數(shù)
var a = new C(); //創(chuàng)建實例
var b = new D(); //創(chuàng)建實例
var bool1=a instanceof C
var bool2=a instanceof D
//bool1是C對象的實例
console.log(bool1)
//bool2不是C對象的實例
console.log(bool2)