1. CSS和JS在網(wǎng)頁(yè)中的放置順序是怎樣的蕉堰?
- 理論上來(lái)說(shuō)旅掂,CSS和JS的放置位置并沒有嚴(yán)格要求泽台,不過(guò)因?yàn)闉g覽器的工作方式原因什荣,出于高性能考慮,通常怀酷,CSS放在html文檔的head標(biāo)簽中稻爬,JS放在文檔的</body>標(biāo)簽之前。
- 原因:瀏覽器會(huì)按照從上到下的順序解析文檔內(nèi)容蜕依,而且默認(rèn)在解析到j(luò)avascript代碼時(shí)桅锄,其他文檔無(wú)法加載或顯示,只有等待javascript代碼下載并執(zhí)行完畢才能顯示文檔样眠。這樣就造成一些問題:
- 如果將JS代碼放在head元素中友瘤,在瀏覽器加載JS代碼時(shí),文檔內(nèi)容不會(huì)顯示檐束,會(huì)等待瀏覽器加載JS代碼完成才能顯示辫秧;
- 如果放在文檔中隨便一個(gè)位置,那么有可能JS代碼比文檔提前執(zhí)行被丧,而一般用戶希望文檔全部加載完成才執(zhí)行JS盟戏。
2. 解釋白屏和FOUC
-
白屏:由于DOM的存在绪妹,以及JS語(yǔ)言作為腳本語(yǔ)言的特點(diǎn),當(dāng)把CSS或JS文件放在html文檔不同位置時(shí)柿究,可能會(huì)出現(xiàn)一些問題喂急,白屏問題就是其中一種。
- CSS:CSS和HTML文檔能夠并發(fā)同步加載笛求,但是當(dāng)把CSS文件放在底部時(shí)廊移,部分瀏覽器會(huì)出現(xiàn)白屏,所以正常情況CSS要放在head標(biāo)簽中探入;而如果使用@import引入CSS文件狡孔,那么即使放在head標(biāo)簽中也可能會(huì)出現(xiàn)白屏。
- JS:JS作為腳本語(yǔ)言蜂嗽,在瀏覽器解析到JS時(shí)會(huì)加載JS苗膝,同時(shí)禁止HTML文檔的下載和顯示,即如果不做屬性處理植旧,正常情況下JS會(huì)影響文檔的顯示出現(xiàn)白屏問題辱揭,所以建議將JS放在文檔</body>標(biāo)簽之上。
- FOUC(Flash Of Unstyled Content):無(wú)樣式文本閃爍病附,顧名思義问窃,當(dāng)把CSS樣式表放在文檔的不同部位時(shí),會(huì)有不同顯示效果完沪,如果放在文檔底部域庇,在加載完文檔之后才應(yīng)用樣式,每一層DOM都會(huì)加載覆积,故而發(fā)生文檔閃爍听皿。其中常見于IE瀏覽器,而這種CSS放在底部的情況宽档,F(xiàn)irefox瀏覽器會(huì)一直閃爍尉姨。
3. async和defer的作用是什么?有什么區(qū)別
async
和defer
是<script>
標(biāo)簽的兩個(gè)屬性吗冤,用于指定腳本文件的加載方式又厉。正常情況下,瀏覽器從上到下解析HTML文件欣孤,當(dāng)解析到<script>
標(biāo)簽的時(shí)候會(huì)立即下載腳本并執(zhí)行馋没,只有當(dāng)加載執(zhí)行腳本之后瀏覽器才能繼續(xù)解析<script>
標(biāo)簽之后的文檔內(nèi)容,而async
和defer
屬性就是改變這種加載方式的作用降传。
-
async:表示應(yīng)該立即下載腳本篷朵,不影響頁(yè)面其他操作諸如其他腳本的下載,
async
屬性會(huì)使加載和渲染文檔元素的過(guò)程和JS腳本加載和執(zhí)行并行進(jìn)行(即異步)。只對(duì)外部腳本文件有效声旺。 - defer:表示腳本可以延遲到文檔完全被解析之后再執(zhí)行笔链。只對(duì)外部腳本文件有效,IE7及更早版本對(duì)嵌入腳本也支持這個(gè)屬性腮猖。
-
區(qū)別:
- async:不保證按照指定順序執(zhí)行JS腳本鉴扫,第二個(gè)JS可能會(huì)比第一個(gè)JS文件先執(zhí)行。所以多個(gè)JS文件若設(shè)置此屬性應(yīng)避免依賴澈缺。
<<script src="script-1.js"></script>
<<script src="script-2.js"></script>
- defer:腳本延遲到文檔完全解析渲染后按照順序執(zhí)行坪创。
4. 簡(jiǎn)述網(wǎng)頁(yè)的渲染機(jī)制
- 解析HTML標(biāo)簽,構(gòu)建DOM樹
- 解析CSS文件姐赡,構(gòu)建CSSOM渲染樹
- DOM樹和CSSOM樹組合莱预,形成渲染樹(render tree)
-
Render樹構(gòu)建好了之后,將會(huì)執(zhí)行布局過(guò)程项滑,它將確定每個(gè)節(jié)點(diǎn)在屏幕上的確切坐標(biāo)依沮。再下一步就是繪制,即遍歷render樹枪狂,并使用UI后端層繪制每個(gè)節(jié)點(diǎn)危喉。即在渲染樹的基礎(chǔ)上進(jìn)行布局, 計(jì)算每個(gè)節(jié)點(diǎn)的幾何結(jié)構(gòu)把每個(gè)節(jié)點(diǎn)繪制到屏幕上 (painting)
5. JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是簡(jiǎn)單類型?哪些是復(fù)雜類型?
Javascript定義了5種簡(jiǎn)單數(shù)據(jù)類型,1種復(fù)雜數(shù)據(jù)類型
- 簡(jiǎn)單數(shù)據(jù)類型:
- undefined:未定義或不存在州疾;
<script>
var test1;
alert(test1);
alert(test2);
</script>
代碼中聲明了test1變量辜限,但并未初始化,而未聲明test2孝治,效果如下:
只顯示一次undefined列粪,不同瀏覽器處理方式不同,有些不會(huì)無(wú)視而是顯示錯(cuò)誤谈飒。這就說(shuō)明了:未初始化的聲明變量值為undefined,未聲明變量沒有值态蒂,會(huì)顯示錯(cuò)誤杭措,但是有一個(gè)現(xiàn)象如下:
<script>
var test1;
alert(typeof test1);
alert(typeof test2);
</script>
對(duì)未聲明變量使用typeof操作時(shí),會(huì)顯示類型為undefined:
這也就是undefined的含義:未定義或不存在钾恢。
- null:空對(duì)象指針手素,雖然是單獨(dú)的數(shù)據(jù)類型,但是用typeof操作時(shí)瘩蚪,顯示其為對(duì)象類型:
<script>
alert(typeof null);
</script>
-
boolean:布爾值泉懦,即true或false;兩者就是布爾值疹瘦,和0或1不是一回事崩哩。對(duì)于平時(shí)的0對(duì)應(yīng)false,1對(duì)應(yīng)true那是用轉(zhuǎn)型函數(shù)boolean()實(shí)現(xiàn)的:
- number:
- 整數(shù):十進(jìn)制,八進(jìn)制(0開頭)邓嘹,十六進(jìn)制(0x開頭)酣栈;
- 浮點(diǎn)數(shù):帶小數(shù)點(diǎn)的數(shù),對(duì)于極值用科學(xué)計(jì)數(shù)法表示汹押,例如var floatnum = 3e-17矿筝,默認(rèn)情況帶有6個(gè)0的浮點(diǎn)數(shù)會(huì)自動(dòng)轉(zhuǎn)換為e表示法;0.1+0.2=0.30000000000000004這是由于IEEE754浮點(diǎn)計(jì)算通病所致棚贾,所以不能用浮點(diǎn)數(shù)進(jìn)行條件測(cè)試窖维;
- NaN(not a number):意為非數(shù)值,但是其類型本身就是數(shù)值妙痹;
<script>
alert(0 / 0);
alert(2 / 0);
alert(-2 / 0);
</script>
可以看出和數(shù)學(xué)中的概念是如出一轍的陈辱;
NaN不等于本身:
<script>
if(NaN == NaN) {
alert("NaN等于本身");
} else {
alert("NaN不等于本身");
}
</script>
NaN的任何操作都返回NaN:
<script>
alert(NaN / 10);
</script>
ifNaN()函數(shù):意為是否不是數(shù)值,除了NaN本身和不帶數(shù)字的字符串是true细诸,其他都是false沛贪,因?yàn)楹瘮?shù)會(huì)自動(dòng)將數(shù)據(jù)類型轉(zhuǎn)型為number并判斷是否不是數(shù)值。
- string:字符串類型震贵,一旦創(chuàng)建值就不變利赋,要改變其所在變量值,需要先銷毀字符串然后填充新字符串猩系;
-
object:對(duì)象類型媚送,較為復(fù)雜,意為一組數(shù)據(jù)和功能的集合寇甸,包含屬性和方法塘偎。
還有諸多的知識(shí),但是屬于細(xì)節(jié)拿霉,在此不再贅述吟秩,采用思維導(dǎo)圖進(jìn)行整理如下:
鏈接:http://pan.baidu.com/s/1nuED7qp 密碼:1oom
6. NaN、undefined绽淘、null分別代表什么?
在上面的數(shù)據(jù)類型介紹中已經(jīng)詳細(xì)介紹涵防,在此簡(jiǎn)單再回顧下:
- NaN:意為非數(shù)值,不等于任何值包括其本身沪铭;
-
undefined:意為未定義或不存在壮池,當(dāng)代碼并沒有返回值時(shí),會(huì)顯示
undefined
杀怠,而不是錯(cuò)誤椰憋; -
null:是空對(duì)象指針,一種簡(jiǎn)單數(shù)據(jù)類型赔退,但是用
typeof
操作時(shí)顯示其為object類型橙依;這是一個(gè)歷史遺留問題。在 JavaScript 最初的實(shí)現(xiàn)中,JavaScript 中的值是由一個(gè)表示類型的標(biāo)簽和實(shí)際數(shù)據(jù)值表示的票编。對(duì)象的類型標(biāo)簽是0褪储。由于null
代表的是空指針(大多數(shù)平臺(tái)下值為0x00),因此慧域,null
的類型標(biāo)簽也成為了0鲤竹,typeof null
就錯(cuò)誤的返回了object
. -
另外,null昔榴、undefined是等于自身的辛藻。null==undefined,但不嚴(yán)格相等:
7. typeof和instanceof的作用和區(qū)別?
typeof是檢測(cè)給定數(shù)據(jù)的數(shù)據(jù)類型互订,而instanceof檢測(cè)給定數(shù)據(jù)的對(duì)象類型吱肌。
JavaScript 中 typeof 和 instanceof 常用來(lái)判斷一個(gè)變量是否為空,或者是什么類型的仰禽。但它們之間還是有區(qū)別的:
- typeof:是一個(gè)一元運(yùn)算符氮墨,放在運(yùn)算數(shù)之前,運(yùn)算數(shù)可以是任何類型吐葵。它會(huì)返回一個(gè)字符串顯示數(shù)據(jù)類型规揪;
-
instanceof:是一個(gè)二元運(yùn)算符,用于判斷某個(gè)變量是否為對(duì)象的實(shí)例:
可以看出温峭,數(shù)組a進(jìn)行instanceof操作時(shí)猛铅,不僅會(huì)顯示為Array的實(shí)例,同時(shí)也是Object的實(shí)例凤藏,因?yàn)锳rray是Object的子集奸忽。
談到 instanceof 我們要多插入一個(gè)問題,就是 function 的 arguments揖庄,我們大家也許都認(rèn)為 arguments 是一個(gè) Array栗菜,但如果使用 instaceof 去測(cè)試會(huì)發(fā)現(xiàn) arguments 不是一個(gè) Array 對(duì)象,盡管看起來(lái)很像抠艾。
<script>
var a = new Array();
if(a instanceof Object) {
alert(true);
} else {
alert(false);
}
if(window instanceof Object) {
alert(true);
} else {
alert(false);
}
alert(typeof window);
</script>
代碼有3個(gè)彈窗苛萎,分別是true,true检号,object,并且在IE11測(cè)試下效果相同蛙酪,說(shuō)明齐苛,instanceof在新版主流瀏覽器中,即是指ES的對(duì)象類型桂塞,也是指DOM的對(duì)象模型凹蜂。
代碼:
1. 完成如下代碼判斷一個(gè)變量是否是數(shù)字、字符串、布爾玛痊、函數(shù) (難度*)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-1</title>
</head>
<body>
<script>
function isNumber(el){
if(typeof el == "number") {
return true;
} else {
return false;
} // todo ...
}
function isString(el){
if(typeof el == "string") {
return true;
} else {
return false;
}//todo ...
}
function isBoolean(el){
if(typeof el == "boolean") {
return true;
} else {
return false;
}//todo ...
}
function isFunction(el){
if(typeof el == "function") {
return true;
} else {
return false;
}//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é)果是?(難度**)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-2</title>
</head>
<body>
<script>
console.log(1+1);
console.log("2"+"4");
console.log(2+"4");
console.log(+new Date()); // 1971年至今的毫秒數(shù)
console.log(+"4");
</script>
</body>
</html>
3. 以下代碼的輸出結(jié)果是? (難度***)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-3</title>
</head>
<body>
<script>
var a = 1;
console.log(a+++a);
console.log(typeof a+2); // typeof先執(zhí)行汰瘫,+連接前后運(yùn)算數(shù)
</script>
</body>
</html>
4. 遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方 (難度**)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-4</title>
</head>
<body>
<script>
var arr = [3,4,5];
for(var i = 0; i < arr.length; i++) {
console.log(arr[i] * arr[i]);
}
</script>
</body>
</html>
5. 遍歷 JSON, 打印里面的值 (難度**)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-5</title>
</head>
<body>
<script>
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for(var a in obj) {
console.log(a + ":" + obj[a])
}//todo ...
// 輸出 name: hunger, sex: male, age:28
</script>
</body>
</html>
6. 下面代碼的輸出是? 為什么 (難度***)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task16-6</title>
</head>
<body>
<script>
console.log(a); //undefined擂煞,變量提升
var a = 1;
console.log(a); //1
console.log(b); //錯(cuò)誤混弥,未聲明變量
</script>
</body>
</html>
原因:在JS腳本中,在本身作用域內(nèi)的變量會(huì)提升到代碼最上方对省,但是其值不會(huì)跟隨提升蝗拿,所以第一個(gè)顯示undefined意為“未定義”,而代碼中未聲明b蒿涎,所以顯示錯(cuò)誤哀托。
本文版權(quán)歸本人和饑人谷所有,轉(zhuǎn)載請(qǐng)注明來(lái)源劳秋,謝謝