1.CSS和JS在網(wǎng)頁(yè)中的放置順序是怎樣的陆蟆?
CSS一般放在head標(biāo)簽,因?yàn)镃SS加載時(shí)可以并發(fā)請(qǐng)求(IE6除外)惋增,不阻礙其他資源的同時(shí)加載叠殷。這樣對(duì)于網(wǎng)速緩慢的用戶在瀏覽網(wǎng)頁(yè)時(shí)能夠讓內(nèi)容和樣式更為順暢的顯示出來(lái),從而提高用戶體驗(yàn)诈皿,優(yōu)化網(wǎng)頁(yè)性能
JS一般放在body標(biāo)簽的尾部林束,因?yàn)镴S加載時(shí)是阻塞加載,即JS需要加載完成后才加載其他資源稽亏,為了避免這一問(wèn)題壶冒,故將JS放置到尾部能夠在不影響頁(yè)面呈現(xiàn)前提下,實(shí)現(xiàn)JS資源的后續(xù)下載
2.解釋白屏和FOUC
所謂白屏截歉,是指CSS渲染時(shí)間過(guò)長(zhǎng)胖腾,而HTML元素的渲染在CSS之后,導(dǎo)致瀏覽器視窗出現(xiàn)白屏——什么內(nèi)容也沒(méi)有瘪松,一片空白的現(xiàn)象咸作。
常見(jiàn)于對(duì)于IE、chrome等瀏覽器宵睦,若將css放在body標(biāo)簽底部记罚,頁(yè)面會(huì)等css加載完后才顯示內(nèi)容;另一種情況是若使用@import標(biāo)簽引用樣式壳嚎,即便css放在head標(biāo)簽桐智,也可能出現(xiàn)白屏所謂FOUC,全稱叫做Flash of Unstyled Content烟馅,中文名為無(wú)樣式內(nèi)容閃爍说庭,是指瀏覽器先對(duì)HTML元素進(jìn)行渲染,然后等CSS加載完后重新對(duì)頁(yè)面的樣式進(jìn)行渲染一次導(dǎo)致的頁(yè)面樣式的突然閃現(xiàn)現(xiàn)象
常見(jiàn)于將css內(nèi)容放在body標(biāo)簽尾部
3.async和defer的作用是什么郑趁?有什么區(qū)別
js在頁(yè)面加載時(shí)遵循同步加載的原則口渔,就如同HTML在渲染時(shí)遵循flow based layout,除非出現(xiàn)float/position/overlfow等改變正常文檔流的定位機(jī)制穿撮。
同理缺脉,async和defer都是改變js同步加載的兩種方法痪欲,可以改變js同步加載導(dǎo)致的網(wǎng)頁(yè)性能優(yōu)化問(wèn)題。
- defer是script標(biāo)簽中處理腳本運(yùn)行的屬性之一攻礼,中文稱作延時(shí)业踢,作用是js在頁(yè)面加載后才會(huì)運(yùn)行腳本,即同時(shí)加載js礁扮,延時(shí)執(zhí)行js知举。
語(yǔ)法規(guī)則為:
<script src="demo.js" defer="defer"></script>
- async(HTML5)是script標(biāo)簽中處理腳本運(yùn)行的另一屬性,中文稱作異步太伊,作用是腳本會(huì)異步加載而不阻塞頁(yè)面加載雇锡,并且js一旦下載完畢就會(huì)立即執(zhí)行。
<script src="demo.js" async="async"></script>
關(guān)于二者的加載和執(zhí)行方式如下圖所示:
【注意】無(wú)論是defer還是async都僅適用于外部腳本
-
defer和async的比較
相同點(diǎn):
加載文件時(shí)不阻塞頁(yè)面渲染僚焦;
對(duì)于inline的script無(wú)效锰提;
使用這兩個(gè)屬性的腳本中不能調(diào)用document.write方法;
有腳本的onload的事件回調(diào)芳悲;
允許不定義屬性值立肘,僅僅使用屬性名;
不同點(diǎn):
html的版本html4.0中定義了defer名扛;html5.0中定義了async谅年;這將造成由于瀏覽器版本的不同而對(duì)其支持的程度不同;
執(zhí)行時(shí)刻:每一個(gè)async屬性的腳本都在它下載結(jié)束之后立刻執(zhí)行肮韧,同時(shí)會(huì)在window的load事件之前執(zhí)行融蹂。所以就有可能出現(xiàn)腳本執(zhí)行順序被打亂的情況;每一個(gè)defer屬性的腳本都是在頁(yè)面解析完畢之后弄企,按照原本的順序執(zhí)行超燃,同時(shí)會(huì)在document的DOMContentLoaded之前執(zhí)行。
4.簡(jiǎn)述網(wǎng)頁(yè)的渲染機(jī)制
- 解析文檔并構(gòu)建樹(shù):Html解析以構(gòu)建DOM Tree和Css解析以構(gòu)建Style Rules Tree
- 構(gòu)建渲染樹(shù)Render Tree:此時(shí)渲染引擎會(huì)將DOM Tree和Style Rules Tree結(jié)合在一起形成Render樹(shù)桩蓉,它由一些包含有顏色和大小等屬性的矩形組成
- 布局Layout:Render樹(shù)構(gòu)建好了之后,將會(huì)執(zhí)行布局過(guò)程劳闹,它將確定每個(gè)節(jié)點(diǎn)在屏幕上的確切坐標(biāo)院究。
-
繪制paint:再下一步就是繪制,即遍歷render樹(shù)本涕,并使用UI后端層繪制每個(gè)節(jié)點(diǎn)业汰。
5.JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是簡(jiǎn)單類型?哪些是復(fù)雜類型?
六大數(shù)據(jù)類型:數(shù)值型、字符串型菩颖、布爾型样漆、對(duì)象、數(shù)組晦闰、函數(shù)
簡(jiǎn)單類型:數(shù)值型放祟、字符串型鳍怨、布爾型
復(fù)雜類型:對(duì)象、數(shù)組跪妥、函數(shù)
【注】
1.數(shù)組和函數(shù)算是廣義的對(duì)象鞋喇,null也屬于對(duì)象
2.NaN是一種特殊的數(shù)值
6.NaN、undefined眉撵、null分別代表什么?
- NaN:表示Not a Number侦香,不是一種獨(dú)立的數(shù)據(jù)類型,而是一種特殊數(shù)值纽疟,它的數(shù)據(jù)類型依然屬于Number罐韩,只不過(guò)數(shù)值計(jì)算時(shí)不符合計(jì)算法則
0/0//NaN
Math.sqrt(-5)//NaN
- null是一個(gè)表示"無(wú)"的對(duì)象,轉(zhuǎn)為數(shù)值時(shí)為0污朽;
- undefined是一個(gè)表示"無(wú)"的原始值散吵,轉(zhuǎn)為數(shù)值時(shí)為NaN。
也就是說(shuō):關(guān)于null和undefined的使用場(chǎng)景膘壶,object初始化時(shí)最好使用null,而基本數(shù)據(jù)類型最好使用undefined ,但是二者在本質(zhì)上是沒(méi)有區(qū)別的错蝴,是JS的一個(gè)bug!
7.typeof和instanceof的作用和區(qū)別?
-
typeof是返回一個(gè)字符串并顯示為參數(shù)數(shù)據(jù)類型的運(yùn)算符,但它無(wú)法區(qū)分?jǐn)?shù)據(jù)類型object究竟是出自狹義的對(duì)象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運(yùn)算符可以用來(lái)判斷某個(gè)構(gòu)造函數(shù)的prototype屬性所指向的對(duì)象是否存在于另外一個(gè)要檢測(cè)對(duì)象的原型鏈上颓芭,簡(jiǎn)單的講就是判斷一個(gè)變量是否是某個(gè)對(duì)象(類)的實(shí)例顷锰,返回值是布爾類型的。
function C(){}
function D(){}
var a = new C();
var b = new D();
var bool1=a instanceof C
var bool2=a instanceof D
//bool1是C對(duì)象的實(shí)例
console.log(bool1)
//bool2不是C對(duì)象的實(shí)例
console.log(bool2)
- typeof 和 instanceof 應(yīng)用實(shí)例
8.代碼題
1.完成如下代碼判斷一個(gè)變量是否是數(shù)字亡问、字符串官紫、布爾、函數(shù)
- 代碼錄入操作
function isNumber(el){
if (typeof el === "number"){
return true;
} else {
return false;
}
}
function isString(el) {
if (typeof el === "string"){
return true;
} else {
return false;
}
}
function isBoolean(el){
if (typeof el === "boolean"){
return true;
} else {
return false;
}
}
function isFunction(el){
if (typeof el === "function"){
return true;
} else{
return false;
}
}
var a = 3.14,
b = "hello world",
c = false,
d=function D(){};
console.log(isNumber(a));//true
console.log(isString(b));//true
console.log(isBoolean(c));//true
console.log(isFunction(d));//true
console.log(isNumber(b));//false
console.log(isString(d));//false
console.log(isBoolean(a));//false
console.log(isFunction(c));//false
2.以下代碼的輸出結(jié)果是?
console.log(1+1); //2
console.log("2"+"4"); //24
console.log(2+"4"); //24
console.log(+new Date()); //1465811462860
console.log(+"4"); //4
3.以下代碼的輸出結(jié)果是?
var a = 1;
a+++a;
//a++ -> a+1=2 ->2+a = 3州藕,即a+++a返回值為3
typeof a+2;
/typeof a -> "number" -> "number" + 2 -> "number2"束世,即"number2"
4.遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方
//for 循環(huán)方法
var arr = [3,4,5];
for (i=0;i<arr.length;i++){
array=Math.pow(arr[i],2);
console.log(array);
}
//while 循環(huán)方法
var i = 0;
while (i < arr.length){
array=Math.pow(arr[i],2);
console.log(array);
i++;
}
//do while 循環(huán)方法
do {
array=Math.pow(arr[i],2);
console.log(array);
i++;
}while(i < arr.length)
5.遍歷 JSON, 打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
};
var key;
for (key in obj){
console.log(key + ":" + obj[key])
}
6.下面代碼的輸出是? 為什么
console.log(a);
var a = 1;
console.log(a);
console.log(b);
//相當(dāng)于
var a;
console.log(a);//undefined
a=1;
console.log(a)//1
console.log(b)//b is not defined
由于js存在變量提升機(jī)制床玻,使得a的聲明提升至最前面毁涉,此時(shí)由于a只聲明未賦值,所以數(shù)據(jù)類型為undefined锈死;
到了a=1時(shí)贫堰,輸出1;
最后待牵,由于b為聲明其屏,所以控制臺(tái)報(bào)錯(cuò)。
參考資料
網(wǎng)站前端性能優(yōu)化之javascript和css
js和css放置位置
引用JavaScript文件時(shí)的兩個(gè)屬性defer和async
HTML 5 <script> async 屬性
HTML 5 <script> defer 屬性
instanceof和typeof運(yùn)算符的區(qū)別詳解