javascript語法、數據類型基礎知識問答

一、問答

(一)CSS和JS在網頁中的放置順序是怎樣的?

1、對于css:當引用css文件時,應放在文件的頭部<head>標簽內,當直接在html文檔中書寫時則應在<head>內新建一個<style>標簽,再將其放在<style>標簽中;
2、對于js:考慮到js會阻塞后面的內容的加載,因此通常將js放在<body>元素中頁面的內容的后面,當然這也不是絕對的,例如個別特殊JS,比如用于調試的基礎腳本(部署時未必有)、性能日志之類,必須放在盡量最前的位置。再比如 html5-shim腳本必須在body之前加載。
另外,雖然將js放在<body>元素中頁面的內容的后面是比較推薦的做法,但對于一些老的瀏覽器,IE8以下,js與js間也會相互阻塞,這時可采用“動態加載”或“LABjs庫的”方法,具體可詳見:并行加載與順序執行–《高性能javascript》讀書筆記

值得注意的是有些網站制作開發者從性能優化的角度傾向于加defer,不過不是所有的腳本都能這樣做。比如history api的兼容實現等都不應defer,因為你不能確保用戶在頁面ready之前沒有back/forward動作。再如jQuery,defer是可以,但也意味著你所有依賴jQuery的功能都需要defer,考慮到這些靜態文件通常都是有緩存的,所以不defer也未必不是一個可以接受的折衷。
另:雖然js能夠支持不使用外部引用的方式(即采用嵌入HTML的方式),但還是推薦使用外部引入的方式,因為這樣1、可維護性相對較好;2、可緩存;(但兩個頁面使用同一個js時,當一個頁面下載了,另一個頁面可共用該緩存);3、適應未來;

(二)解釋白屏和FOUC

  • 1、 白屏
    a、如果將樣式放在頁面底部,使用IE瀏覽器進行刷新、新建窗口打開時均會出現白屏,出現白屏的原因是因為IE想要等待所有樣式及內容全部解析后才呈現出來,否則會出現FOUC的現象;
    b、如果使用 @import 標簽,即使 CSS 放入 link, 并且放在頭部,也可能出現白屏;
    c、如果將js放在頁面的頭部也會可能出現白屏現象,因為js會阻塞后面內容的加載,直至其自身被加載完成后(當然如果在js中使用 defer 或 async則另當別論)

  • 2、 FOUC

FOUC 全稱為Flash of Unstyled Content,即無樣式內容閃爍,出現這種情況的原因是將樣式放在了頁面的底部,瀏覽器在加載頁面時先加載了內容,然后才加載樣式,從而導致這樣的情況發生;對于IE瀏覽器,如果采用輸入URL、使用書簽及點擊鏈接等方式易出現 FOUC;對于火狐則一直表現出這樣的情況。原因是火狐考慮到用戶體驗,采用逐步加載頁面中的組件的方式;

另: 一個style塊可以包含多個@import規則,但@import規則必須放在所有其他規則之前。 使用@import規則需要注意的是:即便把@import規則放在文檔的HEAD標簽中,可能導致頁面組件下載時的無序性,進而導致白屏(對于IE)和FOUC(對于FF)問題的產生。 為了很好的避免白屏和FOUC問題,請遵循以下規則: 使用LINK標簽將樣式表放在文檔的HEAD中。

(三)async和defer的作用是什么?有什么區別?

  • async---異步腳本,作用是:告訴瀏覽器立刻下載其指定的js,與此同時會同步加載頁面的內容部分,不會因為js的存在而導致瀏覽器必須先下載并執行js后再加載后面的內容;(因此建議異步腳本不要在加載期間修改DOM)
  • defer--延遲腳本,作用是遇到js時立即下載,但延遲到</html>之前的內容全部加載完后再執行;這樣不會因此js的存在導致阻塞了后面的頁面內容的呈現;

值得一提的是,async和defer均只適用在外部js文本,不支持嵌入式腳本;【對于defer,老版本瀏覽器(如IE4~7)除外】

  • 區別:
    1、執行時間不一樣:async的js在下載完后會立即執行(因此腳本在代碼中的順序并不是腳本所執行的先后順序,有可能后面出現的腳本先執行),但defer則要等待整個頁面內容及樣式全部加載完后再執行;(HTML5規范要求腳本執行應該按照腳本出現的先后順序執行,但實際情況下,延遲腳本不一定按照先后順序執行!!!)
    2、HTML版本不一樣:html的版本html4.0中定義了defer;html5.0中定義了async;
    3、瀏覽器支持情況不一樣
瀏覽器支持情況不一樣.png

(四)簡述網頁的渲染機制

一個網頁的渲染機制基本是這樣的:解析HTML以構建DOM樹--構建render樹--布局render樹 --繪制render樹 ;


Paste_Image.png

首先解析HTML,解析時將標簽作為內容樹中的BOM節點,然后解析css樣式,這些css樣式及HTML可見性指令被用來構建render樹,render樹由一些大小和顏色等屬性組成的矩形按照順序投影至屏幕上,render樹構建好后,將進行布局過程,它將確定各個節點在屏幕上并進行下一步驟--繪制,也即遍歷render樹,并使用UI后端層繪制每個節點;需要說明的是,為了用戶體驗,并不是等待HTML完全解析完才繪制render樹的,而是解析完一部分內容就展示一部分內容的;
具體可詳見:http://taligarsiel.com/Projects/howbrowserswork1.htm

http://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/?from=timeline&isappinstalled=0

Webkit內核流程:

Webkit內核.png

Mozilla's Gecko內核流程

Mozilla's Gecko內核.png
CSSparsing過程.png

(五)JavaScript 定義了幾種數據類型? 哪些是簡單類型?哪些是復雜類型?

定義了2大類型,一個是簡單型另一個是復雜型,簡單型里包括Null型、Undefined型、Number型、String(字符串型)、Boolean(布爾型);復雜型其實指Object型,里面包括函數、狹義對象及數組。

(六)NaN、undefined、null分別代表什么?

  • NaN---非數值(Not a Number)屬于Number類型的特殊的一種類型,它用來表示本來應該返回數值的操作數未返回數值的情況(這樣就不會報錯了,繼而會繼續執行其他的代碼,在其他語言有可能會報錯導致后面的代碼停止執行),比如任何數值除以非數值會返回NaN;例如:
var wo="peple" // 
undefined
0/wo
NaN
wo/0
NaN

以上,一個數值除以一個字符串,則返回了NaN;

  • undefined表示使用var聲明了變量,但未給它進行初始化(即賦值給它)
    如下面的例子:
var a;
undefined
a
undefined
  • null表示空對象指針(雖然它并不是對象,但從邏輯的角度講它是一個對象,因此typeof它時,返回的值是Object--如下圖所示),如果在意保存對象的變量還沒有真正保存對象,可明確的讓該變量值為null;
Paste_Image.png

(七)typeof和instanceof的作用和區別?

  • typeof的作用是可以展示數據是什么類型,但是對于null、Array數組、對象它均識別成Object;typeof可以返回的值有:undefined、number、object、Boolean、string、function;
對于null,typeof返回為object.png
對于數組返回object.png
對象返回對象.png

另:一般來說使用typeof的操作是直接量形式的話能夠返回準確的結果,如果是使用構造函數創建的對象則會返回"object",不過對于數組來說是個例外,無論是否是直接量都會返回"object"。

  • instanceof可以判斷某個變量是否是個對象或者一個對象是否是個數組;
    如下面的例子:
Paste_Image.png
判斷suzu是否為數組.png

另:它還可以判斷一個變量是否是某個對象(類)的實例,返回值是布爾類型。

var str=new String("antzone");  
console.log(str instanceof String);

以上代碼會輸出true,因為str是對象String的對象實例。一般說來只有使用構造函數創建的對象才會返回true,否則返回false,不過數組是一個例外,都會返回true。
再如:function test(){};var a=new test();alert(a instanceof test)會返回true。談到instanceof我們要多插入一個問題,就是function的arguments,我們大家也許都認為arguments是一個Array,但如果使用instaceof去測試會發現arguments不是一個Array對象,盡管看起來很像。
另外:

測試 var a=new Array();if (a instanceof Object) alert('Y');else alert('N');
得'Y’

但 if (window instanceof Object) alert('Y');else alert('N');

得'N'

所以,這里的instanceof測試的object是指js語法中的object,不是指dom模型對象。

使用typeof會有些區別
alert(typeof(window) 會得 object;

  • 區別:1、很明顯,綜上所述,大部分它們的使用場景不一樣;2、輸出結果不一樣---typeof會輸出6種值即undefined、number、object、Boolean、string、function,而instanceof只會輸出兩者值要么true要么false;3、語法結構不一樣---typeof 的結構為 “typeof 測試對象;”,而instanceof的結構為“測試對象 instanceof 類型”;

二、代碼

(一)完成如下代碼判斷一個變量是否是數字、字符串、布爾、函數 (難度*)

ps: 做完后可參考 underscore.js 源碼中部分實現

function isNumber(el){
    // todo ...
}
function isString(el){
    //todo ...
}
function isBoolean(el){
    //todo ...
}
function isFunction(el){
    //todo ...
}

var a = 2,
    b = "ji",
    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>Document</title>
</head>
<body>
    <div></div>
    <script>
      var a=2,
          b="ji",
          c=false;
      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";
      }
      alert(isNumber(a));
      alert(isString(a));        
      alert(isString(b)); 
      alert(isBoolean(c));      
      alert(isFunction(a)); 
      alert(isFunction(isNumber)); 

    </script>
</body>
</html>

(二)以下代碼的輸出結果是?(難度**)

console.log(1+1);  //2
console.log("2"+"4");  //24    加了""表示字符串了,不會把它當作數字;
console.log(2+"4"); //24 
console.log(+new Date()); // 1470310918153
console.log(+"4");// 4 

(三)以下代碼的輸出結果是? (難度***)

var a = 1;
a+++a;

typeof a+2;

結果是:"number2",原因是:typeof運算級高于賦值及+++等,因此a在typeof上并未來得及賦值,因此a為number;

(四)遍歷數組,把數組里的打印數組每一項的平方 (難度**)

var arr = [3,4,5]
// todo..
// 輸出 9, 16, 25 
打印版.png
未打印版.png

(五)遍歷 JSON, 打印里面的值 (難度**)

var obj = {
  name: 'hunger',
  sex: 'male',
  age: 28
}
//todo ...
// 輸出 name: hunger, sex: male, age:28
Paste_Image.png

(六)下面代碼的輸出是? 為什么 (難度***)

var a = 1;
console.log(a);
console.log(b);

輸出結果一個是1,另一個報錯,顯示“b is not defined(…)”;原因如下

var a = 1; //將1賦值給了a,此時a為1;
console.log(a);//輸出時,將1輸出;
console.log(b);//輸出時,因為b未定義為變量,且b為一個普通的字母,不代表任何含義,因此會出現錯誤說b沒有被定義;

(七)、obeject.key與object[key]有什么區別

1、當對象的屬性key不確定而是一個變量的時候必須使用[]


屬性名為變量

2、[]里可以是任意字符串,而. 不能
3、使用. 號key可以不加引號 使用[] key有時候必須要加引號
例如:

var   a=[{ "0": "./images/1臥室/母子床1.jpg" }, { "1": "images/1臥室/母子床1.jpg" }]
Paste_Image.png

**本文版權歸本人即簡書筆名:該賬戶已被查封 所有,如需轉載請注明出處。謝謝! *

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容