問答
1.CSS和JS在網(wǎng)頁中的放置順序是怎樣的掷空?
一般把css放在<head>
標(biāo)簽內(nèi)肋殴,<title>
標(biāo)簽的后面囤锉;js放在<body>
標(biāo)簽的尾部。這樣做可以避免白屏和FOUC出現(xiàn)护锤。
2.解釋白屏和FOUC
- 白屏:1嚼锄、對于有些瀏覽器,瀏覽器先把樣式加載完全蔽豺,才渲染頁面,展示頁面的內(nèi)容拧粪。對于這樣的瀏覽器修陡,把
<link href='xxx" rel= "stylesheet" type="text/css>
標(biāo)簽放在<body>
尾部時(shí),頁面從上到下開始加載可霎。如果<body>
前面部分的內(nèi)容很復(fù)雜魄鸦,很長,需要加載一段時(shí)間癣朗,然后外聯(lián)的css加載還需要一段時(shí)間拾因,這樣在等待頁面加載的過程中,頁面上沒有內(nèi)容顯示旷余,頁面會(huì)出現(xiàn)白屏绢记。
2、把js文件放在頁面頭部正卧,也會(huì)導(dǎo)致頁面出現(xiàn)白屏蠢熄。頁面從上到下加載。js文件是不能并行加載(即同一時(shí)間只能加載這一個(gè)js文件炉旷,其它的js文件签孔、樣式等都不能加載)的,而且加載后立即執(zhí)行窘行。js執(zhí)行時(shí)饥追,頁面可能還沒有表現(xiàn)出樣式,出現(xiàn)白屏罐盔。 - FOUC:是Flash of Unstyled Content的縮寫但绕,譯為無樣式閃爍。對于有些瀏覽器是先把內(nèi)容顯示出來翘骂,再用外部css文件改變內(nèi)容的樣式壁熄。這時(shí)如果把css文件放在頁面尾部,則頁面先顯示初始內(nèi)容碳竟,然后加載css草丧,一邊加載一邊改變頁面的樣式,頁面的背景莹桅、字體等可能會(huì)有較大變化昌执,頁面會(huì)出現(xiàn)無樣式閃爍烛亦。
舉例:
如果把樣式放在底部,對于IE瀏覽器,在某些場景下(點(diǎn)擊鏈接,輸入U(xiǎn)RL,使用書簽進(jìn)入等),會(huì)出現(xiàn) FOUC 現(xiàn)象(逐步加載無樣式的內(nèi)容,等CSS加載后頁面突然展現(xiàn)樣式).對于 Firefox 會(huì)一直表現(xiàn)出 FOUC .
3.async和defer的作用是什么?有什么區(qū)別
js文件在被加載時(shí)懂拾,有加載后立即執(zhí)行的特點(diǎn)煤禽。“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前岖赋,也就是說不等待后續(xù)載入的文檔元素檬果,讀到就加載并執(zhí)行。這樣把js放在頁面頭部唐断,會(huì)出現(xiàn)白屏选脊。
可以在寫入js文件時(shí)加上async或者defer避免這種情況。
<script async src="script.js"></script>
表示應(yīng)該立即下載腳本脸甘,但不應(yīng)妨礙頁面中的其他操作恳啥,比如下載其他資源或等待加載其他腳本。有 async丹诀,加載和渲染后續(xù)文檔元素的過程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)钝的。但這種方法只對外部腳本文件生效。
<script defer src="script.js"></script>
表示腳本可以延遲到文檔完全被解析和顯示之后再執(zhí)行铆遭。有 defer硝桩,加載后續(xù)文檔元素的過程將和 script.js 的加載并行進(jìn)行(異步),但 script.js 的執(zhí)行要在所有元素解析完成之后疚脐,DOMContentLoaded 事件觸發(fā)之前完成亿柑。只對外部腳本文件有效。 IE7 及更早版本對嵌入腳本也支持這個(gè)屬性棍弄。
區(qū)別:
- defer:腳本延遲到文檔解析和顯示后執(zhí)行望薄,有順序。
- async:不保證順序呼畸,如果
<script async src="example1.js"></script>
<script async src="example2.js"></script>
兩個(gè)腳本都設(shè)置async,第二個(gè)腳本也可能在第一個(gè)腳本之前執(zhí)行痕支。
4.簡述網(wǎng)頁的渲染機(jī)制
1.解析 HTML 標(biāo)簽, 構(gòu)建 DOM 樹
2.解析 CSS 標(biāo)簽, 構(gòu)建 CSSOM 樹
3.把 DOM 和 CSSOM 組合成 渲染樹 (render tree)
4.在渲染樹的基礎(chǔ)上進(jìn)行布局, 計(jì)算每個(gè)節(jié)點(diǎn)的幾何結(jié)構(gòu)把每個(gè)節(jié)點(diǎn)繪制到屏幕上 (painting)
1.參考 課件
2.參考瀏覽器的渲染原理簡介
5.JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是簡單類型?哪些是復(fù)雜類型?
number,undefined蛮原,blooean,string,null,object六種數(shù)據(jù)類型卧须。
簡單類型:
名稱 | 介紹 |
---|---|
number | 數(shù)值類型,包括整數(shù)和小數(shù)儒陨,比如4,3.3花嘶。 |
boolean | 布爾型,有兩個(gè)值true和false蹦漠。 |
string | 字符串型椭员,放在引號(hào)中,比如"abc"笛园。 |
null | 表示空缺隘击,即此處應(yīng)該有一個(gè)值侍芝,但目前為空。 |
undefined | 表示“未定義”或不存在埋同,即此處目前沒有任何值州叠。 |
復(fù)雜類型:object,對象凶赁,各種值組成的集合赖舟。包括數(shù)組财搁,函數(shù)绅你,狹義的對象厉碟。
6.NaN里烦、undefined蒸走、null分別代表什么?
1.NaN代表not a number,非數(shù)字锥债。不等于任何數(shù)包括它自身岸售。
當(dāng)數(shù)字運(yùn)算沒有意義或者不合法時(shí)可以得到NaN错敢。
舉例:
-
NaN不等于任何值翰灾,包括它本身。
- 任何涉及NaN的運(yùn)算都會(huì)返回NaN稚茅。
2.undefined表示“未定義”或不存在纸淮,即此處目前沒有任何值。
典型用法是:
(1)變量被聲明了亚享,但沒有賦值時(shí)咽块,就等于undefined。
(2) 調(diào)用函數(shù)時(shí)欺税,應(yīng)該提供的參數(shù)沒有提供侈沪,該參數(shù)等于undefined。
(3)對象沒有賦值的屬性晚凿,該屬性的值為undefined亭罪。
(4)函數(shù)沒有返回值時(shí),默認(rèn)返回undefined歼秽。
3.null表示空缺应役, 表示一個(gè)值被定義了,定義為“空值”燥筷。
典型用法是:
(1) 作為函數(shù)的參數(shù)箩祥,表示該函數(shù)的參數(shù)不是對象。
(2) 作為對象原型鏈的終點(diǎn)肆氓。
null還有一個(gè)特點(diǎn)typeof null
的值是object袍祖。
這是一個(gè)歷史遺留問題。在 JavaScript 最初的實(shí)現(xiàn)中做院,JavaScript 中的值是由一個(gè)表示類型的標(biāo)簽和實(shí)際數(shù)據(jù)值表示的盲泛。對象的類型標(biāo)簽是0濒持。由于 null代表的是空指針(大多數(shù)平臺(tái)下值為0x00),因此寺滚,null的類型標(biāo)簽也成為了0柑营,typeof null
就錯(cuò)誤的返回了"object". -
NaN,null和undefined的相似點(diǎn):
都可以當(dāng)做false處理函數(shù)。
- null和undefined還相等村视。
可以看出,null蚁孔、undefined是等于自身的奶赔。null==undefined
,但不嚴(yán)格相等杠氢。
7.typeof和instanceof的作用和區(qū)別?
typeof和instanceof都可以判斷數(shù)據(jù)類型站刑。
區(qū)別在于:
typeof對于簡單類型數(shù)值、字符串鼻百、布爾值分別返回number绞旅、string、boolean温艇;undefined返回undefined因悲。null返回object。
對于object(對象)勺爱,除了函數(shù)返回function外晃琳,其它返回object。
對于數(shù)組琐鲁、其它狹義的對象卫旱,可以用instanceof區(qū)分開。instanceof用來判斷某個(gè)變量是否是某個(gè)對象的實(shí)例围段。
instanceof用來檢測對象的類型(也可叫做引用類型誊涯。包含Object、Array蒜撮、Date暴构、RegExp、Function段磨、基本包裝類型(含Boolean取逾、Number、String))苹支。
numberValue是number基礎(chǔ)數(shù)據(jù)類型砾隅,不屬于任何引用類型。
numberObject是object基礎(chǔ)數(shù)據(jù)類型债蜜,屬于Number引用類型(所有引用類型都從Object引用類型繼承而來)晴埂。
代碼題
1.完成如下代碼判斷一個(gè)變量是否是數(shù)字究反、字符串、布爾儒洛、函數(shù) (難度*)
ps: 做完后可參考 underscore.js 源碼中部分實(shí)現(xiàn)
function isNumber(el){
// todo ...
}
function isString(el){
//todo ...
}
function isBoolean(el){
//todo ...
}
function isFunction(el){
//todo ...
}
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
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>任務(wù)16-1</title>
</head>
<body>
<script>
function isNumber(el){
return (typeof el == 'number');// todo ...
}
function isString(el){
return (typeof el == 'string');//todo ...
}
function isBoolean(el){
return (typeof el == 'boolean');//todo ...
}
function isFunction(el){
return (typeof el == 'function'); //todo ...
}
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
</script>
</body>
</html>
2.以下代碼的輸出結(jié)果是?(難度**)
console.log(1+1);//2
console.log("2"+"4");//24
console.log(2+"4"); //24
console.log(+new Date());//從1971年到現(xiàn)在的毫秒數(shù)精耐。
console.log(+"4");//4
3.以下代碼的輸出結(jié)果是? (難度***)
var a = 1;
a+++a;
typeof a+2;//number2
4. 遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方 (難度**)
var arr = [3,4,5]
// todo..// 輸出 9, 16, 25
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var arr=[3,4,5];
for(var i=0; i<arr.length;i++)
document.write(arr[i]*arr[i]+" ");
</script>
</body>
</html>
5.遍歷 JSON, 打印里面的值 (難度**)
var obj = { name: 'hunger', sex: 'male', age: 28}
//todo ...
// 輸出 name: hunger, sex: male, age:28
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
//todo ...
// 輸出 name: hunger, sex: male, age:28
for(var a in obj){
document.write(a+':'+obj.name+" ");
}
</script>
</body>
</html>
6.下面代碼的輸出是? 為什么 (難度***)
console.log(a);//undefined,變量提升琅锻。
var a = 1;
console.log(a);//1
console.log(b);//沒被定義
JavaScript引擎的工作方式是卦停,先解析代碼,獲取所有被聲明的變量恼蓬,然后再一行一行地運(yùn)行惊完。這造成的結(jié)果,就是所有的變量的聲明語句处硬,都會(huì)被提升到代碼的頭部小槐,這就叫做變量提升。
a
在第二句代碼var a=1
中被聲明荷辕,變量a被提升到代碼的頭部本股,所以第一句中a變?yōu)橐讯x但未聲明的變量,console.log(a);
輸出是undefined。
本文版權(quán)歸本人和饑人谷所有桐腌,轉(zhuǎn)載請注明出處