JS基本概念

概念

1、CSS和JS在網(wǎng)頁上的放置順序是怎樣的?

  • 將CSS放在head標(biāo)簽中:CSS放在后面會(huì)造成白屏或者FOUC;
  • 將JS放在最后:腳本會(huì)阻塞后面內(nèi)容的呈現(xiàn)和其后組件的下載,所以JS放在頁面的頂部也會(huì)造成白屏的現(xiàn)象;
  • 這樣做主要是從用戶體驗(yàn)和性能去考慮的。

2、解釋白屏和FOUC

如果樣式放在頭部,不管瀏覽器是加載到什么時(shí)候再解析還是等全部都加載后再解析,都可以在最快的時(shí)間把渲染樹給得到,CSSOM一開始就有了,只要等你內(nèi)容來了,我馬上就可以給它加上,就不會(huì)存在這些現(xiàn)象。

  • 白屏現(xiàn)象樣式

    • 瀏覽器A(比如chrome)如果獲取到的內(nèi)容沒有CSS樣式時(shí),那這些無樣式內(nèi)容就不會(huì)被渲染,所以這時(shí)候就會(huì)出現(xiàn)白屏現(xiàn)象。
      • 在IE瀏覽器當(dāng)中,如果把樣式放在底部,在一些場(chǎng)景當(dāng)中,比如刷新頁面、新窗口打開等,頁面就會(huì)出現(xiàn)白屏,而不是內(nèi)容逐步展現(xiàn)。
      • 如果使用@import標(biāo)簽,即使CSS放入link當(dāng)中且也放在頭部,也有可能會(huì)出現(xiàn)白屏現(xiàn)象。
    • 對(duì)于圖片和CSS,在加載時(shí)會(huì)并發(fā)加載,然而在加載JS文件時(shí)會(huì)禁用并發(fā),阻止其他內(nèi)容的下載。所以把JS代碼放在頁面頂部也會(huì)造成白屏現(xiàn)象。
  • FOUC(Flash Of Unstyled Content)無樣式內(nèi)容閃爍

    • 瀏覽器B(比如firefox)是逐步加載無樣式的內(nèi)容,等CSS加載完成后頁面突然展現(xiàn)的樣子。也就是說,瀏覽器加載了無樣式內(nèi)容,又突然解析到了樣式,會(huì)對(duì)頁面進(jìn)行重新的渲染,這時(shí)候就會(huì)產(chǎn)生FOUC現(xiàn)象;
    • 在IE瀏覽器中,如果把樣式放在底部,某些場(chǎng)景下(點(diǎn)擊鏈接、輸入U(xiǎn)RL、使用書簽進(jìn)入等等),就會(huì)出現(xiàn)FOUC現(xiàn)象。對(duì)于 Firefox 則會(huì)一直表現(xiàn)出 FOUC。

總結(jié)就是:
1、樣式如果放最后,對(duì)于Chrome就會(huì)白屏,對(duì)于Firefox就會(huì)FOUC,IE就比較奇葩,都有可能發(fā)生。
2、JS如果放在最開頭,那就會(huì)白屏。

3、async和defer的作用是什么?有什么區(qū)別

  • 頁面中一個(gè)js文件的完整引入流程:
    1、引入js文件包括加載、解析和執(zhí)行3個(gè)階段
    2、加載js默認(rèn)是同步加載(阻塞加載);
    3、加載完js文件后,根據(jù)響應(yīng)頭信息的內(nèi)容類型Content-Type:application/x-javascript進(jìn)行js文件的解析(預(yù)處理階段),js引擎首先會(huì)解析所有的腳本,然后進(jìn)行變量提升,此時(shí)遇到錯(cuò)誤將不報(bào)錯(cuò);
    4、執(zhí)行js文件,按照腳本和代碼出現(xiàn)的先后順序執(zhí)行,并且遇到錯(cuò)誤報(bào)錯(cuò);

  • 延遲腳本(執(zhí)行階段)

<script src= 'demo.js' defer></scirpt>

上述外部js文件的引入使用了script元素的defer屬性,它將會(huì)改變script元素引入流程過程中的執(zhí)行階段,即延遲執(zhí)行該腳本,直到頁面其他內(nèi)容解析和渲染完畢

  • 異步腳本(加載階段)
<script src='demo.js' async></script>

上述外部js文件的引入使用了script元素的async屬性,它將會(huì)改變scirpt元素引入流程過程中的加載階段,即異步腳本加載過程中不影響頁面其他的操作

如果你在頁面中使用兩個(gè)以上的異步腳本,那么一定要確保二者不存在依賴,不然可能會(huì)導(dǎo)致錯(cuò)誤;

  • 比較async和defer
    • 相同點(diǎn)
      • 加載文件時(shí)不會(huì)阻塞頁面的渲染
      • 只對(duì)外部腳本文件有效
  • 不同點(diǎn)
    • async不保證按照指定它們的先后順序執(zhí)行;
    • defer腳本延遲到文檔解析和顯示后執(zhí)行,會(huì)按照原本給出的順序先后執(zhí)行。

4、簡(jiǎn)述網(wǎng)頁的渲染機(jī)制

  1. 解析HTML以構(gòu)建DOM樹及CSSOM樹,將標(biāo)簽轉(zhuǎn)化為內(nèi)容樹中的DOM節(jié)點(diǎn),接著把外部引用的CSS文件和style標(biāo)簽中的樣式信息解析為CSSOM樹;
  2. 構(gòu)建渲染樹(render樹),由DOM樹及CSSOM樹構(gòu)建而成;
  3. 布局render樹,在render樹的基礎(chǔ)上進(jìn)行布局過程,它將確定每個(gè)節(jié)點(diǎn)在屏幕上的確切坐標(biāo);
  4. 繪制render樹,把每個(gè)節(jié)點(diǎn)繪制到屏幕上;

下面是chrome瀏覽器渲染網(wǎng)頁的機(jī)制:構(gòu)建好DOM樹和CSSOM樹之后再去構(gòu)建渲染樹(也是白屏現(xiàn)象的原因);

webkit瀏覽器渲染網(wǎng)頁的方式

有空看看:瀏覽器內(nèi)部工作原理

5、JavaScript定義了幾種數(shù)據(jù)類型?哪些是簡(jiǎn)單類型?哪些是復(fù)雜類型?

這種分法是從存儲(chǔ)的角度來講的,ECMAScript中有5種簡(jiǎn)單數(shù)據(jù)類型(也稱為基本數(shù)據(jù)類型):Undefined、Null、Boolean、Number和String;還有一種復(fù)雜數(shù)據(jù)類型Object,Object本質(zhì)上是由一組無序的名值對(duì)組成的。

1、Undefined類型:
Undefined類型只有一個(gè)值,即undefined。意為未定義或不存在

  • 在使用var聲明變量但未對(duì)其加以初始化時(shí),這個(gè)變量的值就是undefined。
var message; //這個(gè)變量聲明之后默認(rèn)取得了undefined值
alert(message); //"undefined"
alert(age);   //會(huì)報(bào)錯(cuò)

運(yùn)行上面的代碼,變量message只有一個(gè)值,即“undefined”。

  • 對(duì)未初始化的變量執(zhí)行typeof操作符會(huì)返回undefined值,而對(duì)未聲明的變量執(zhí)行typeof操作符同樣也會(huì)返回undefined值。
var message; //這個(gè)變量聲明之后默認(rèn)取得了undefined值
alert(typeof message); //"undefined"
alert(typeof age); //"undefined"

2、Null類型:
Null類型也只有一個(gè)值,即null。表示空缺,即此處應(yīng)該有一個(gè)值,但目前為空。null值表示空對(duì)象指針,這也是使用typeof檢測(cè)null值時(shí)會(huì)返回"object"的原因。

var car = null; 
alert(typeof car); //"object"

3、Boolean類型:
該類型有兩個(gè)字面值:ture和false。
可以對(duì)任何數(shù)據(jù)類型的值調(diào)用Boolean()函數(shù),而且總會(huì)返回一個(gè)Boolean值,下面是轉(zhuǎn)換規(guī)則:

數(shù)據(jù)類型 轉(zhuǎn)換為ture的值 轉(zhuǎn)換為false的值
Boolean ture false
String 任何非空字符串 ""(空字符串)
Number 任何非零數(shù)字值(包括無窮大) 0和NaN
Object 任何對(duì)象 null
Undefined 不適用 undefined

4、Number類型:

  • 整數(shù)(十進(jìn)制,八進(jìn)制,十六進(jìn)制)
  • 浮點(diǎn)數(shù)(用科學(xué)計(jì)數(shù)法表示,相加不精確,數(shù)值范圍isFinite()函數(shù))
  • NaN,非數(shù)值是一個(gè)特殊的數(shù)值,用來表示一個(gè)本來要返回?cái)?shù)值的操作數(shù)未返回?cái)?shù)值的情況。


    返回NaN的情況

    值NaN有兩個(gè)特點(diǎn):(isNaN()函數(shù))

    • 任何涉及NaN的操作都會(huì)返回NaN;
    • NaN與任何值都不相等,包括NaN本身,如alert(NaN == NaN); //false會(huì)返回false;

對(duì)于非數(shù)值可以用三個(gè)函數(shù)轉(zhuǎn)換為數(shù)值:Number()、parseInt()、parseFloat()
Number()可以用于任何數(shù)據(jù)類型,規(guī)則相當(dāng)復(fù)雜而且不合理,幾乎不使用,常用的是后兩個(gè),專門用于把字符串轉(zhuǎn)換為數(shù)值,規(guī)則類似:

  1. 忽略字符串前面的空白字符,找到第一個(gè)非空白字符;
  2. 如果第一個(gè)字符不是 - 或者數(shù)字返回NaN;
  3. 如果是繼續(xù)解析,直到非數(shù)值模式為止;
  4. 0開頭會(huì)當(dāng)作八進(jìn)制,0x開頭會(huì)當(dāng)作十六進(jìn)制,但是可以指定第二個(gè)參數(shù)指定基數(shù)

5、String類型:
字符串,可以由單引號(hào)或雙引號(hào)表示。
要把一個(gè)值轉(zhuǎn)換為一個(gè)字符串有兩種方法:toString()方法、String()轉(zhuǎn)型函數(shù);

  • 幾乎每個(gè)值都有toString()方法,除了null和undefined值之外;
  • 在不知道要轉(zhuǎn)換的值是不是null或undefined的情況下使用String();


    轉(zhuǎn)換為字符串

6、Object對(duì)象類型:
JavaScript的所有數(shù)據(jù)都可以被視為對(duì)象,這也是我們常說的一切皆為對(duì)象。
對(duì)象類型,較為復(fù)雜,意為一組數(shù)據(jù)和功能的集合,包含屬性和方法。

所以只要包含屬性和功能的一個(gè)集合就可以稱為Object類型,比如,數(shù)組、函數(shù)、“標(biāo)準(zhǔn)”的對(duì)象、時(shí)間對(duì)象、基本包裝對(duì)象、兩個(gè)單體內(nèi)置對(duì)象、正則表達(dá)式都是Object類型。

阮一峰的這個(gè)講得特別好理解:數(shù)據(jù)類型

6、NaN、undefined、null分別代表什么?

  • NaN,非數(shù)值是Number類型中一個(gè)特殊的數(shù)值,用來表示一個(gè)本來要返回?cái)?shù)值的操作數(shù)未返回?cái)?shù)值的情況。


    返回NaN的情況

針對(duì)NaN的這兩個(gè)特點(diǎn),ECMAScript定義了isNaN()函數(shù)。它只有一個(gè)參數(shù),這個(gè)參數(shù)可以是任何類型,該函數(shù)會(huì)幫我們確定這個(gè)參數(shù)是否“不是數(shù)值”。isNaN()接收到一個(gè)值之后,會(huì)嘗試將這個(gè)值轉(zhuǎn)換為數(shù)值。

測(cè)試

  • Undefined數(shù)據(jù)類型:
    Undefined類型只有一個(gè)值,即undefined。意為未定義或不存在
  • 在使用var聲明變量但未對(duì)其加以初始化時(shí),這個(gè)變量的值就是undefined。
var message; //這個(gè)變量聲明之后默認(rèn)取得了undefined值
alert(message); //"undefined"
alert(age);   //會(huì)報(bào)錯(cuò)

運(yùn)行上面的代碼,變量message只有一個(gè)值,即“undefined”。

  • 對(duì)未初始化的變量執(zhí)行typeof操作符會(huì)返回undefined值,而對(duì)未聲明的變量執(zhí)行typeof操作符同樣也會(huì)返回undefined值。
var message; //這個(gè)變量聲明之后默認(rèn)取得了undefined值
alert(typeof message); //"undefined"
alert(typeof age); //"undefined"
  • Null數(shù)據(jù)類型:
    Null類型也只有一個(gè)值,即null。表示空缺,即此處應(yīng)該有一個(gè)值,但目前為空。null值表示空對(duì)象指針,這也是使用typeof檢測(cè)null值時(shí)會(huì)返回"object"的原因。
var car = null; 
alert(typeof car); //"object"

實(shí)際上undefined的值是派生自null值的:


測(cè)試

7、typeof和instanceof的作用和區(qū)別?

因?yàn)镋CMAScript是松散型的,所以需要一種手段來檢測(cè)給定變量的數(shù)據(jù)類型。JS中有三種方法來確定一個(gè)值到底是什么類型。分別為:typeof運(yùn)算符、instanceof運(yùn)算符以及Object.prototype.toString()方法。

  • typeof運(yùn)算符可以返回一個(gè)值的數(shù)據(jù)類型,可能有以下結(jié)果:
    • 原始類型


      原始類型
    • undefined類型
      undefined返回undefined。


      undefined類型

      利用這一點(diǎn),typeof可以用來檢查一個(gè)沒有聲明的變量,而不報(bào)錯(cuò)。


      測(cè)試
    • 函數(shù)
      函數(shù)返回function。
// 定義一個(gè)空函數(shù)
function f(){}
typeof f;  // "function"
- 其它

除此之外都返回object

返回對(duì)象類型

從上面代碼可以看到,空數(shù)組([])的類型也是object,這表示在JavaScript內(nèi)部,數(shù)組本質(zhì)上只是一種特殊的對(duì)象。另外,null的類型也是object,這是由于歷史原因造成的,為了兼容以前的代碼,后來就沒法修改了,并不是說null就屬于對(duì)象,本質(zhì)上null是一個(gè)類似于undefined的特殊值。

  • instanceof則為判斷一個(gè)對(duì)象是否為某一數(shù)據(jù)類型,或一個(gè)變量是否為一個(gè)對(duì)象的實(shí)例,返回Boolean類型。
    對(duì)于用typeof判斷都為Object的對(duì)象我們就可以用instanceof加以判斷:


    結(jié)果

JavaScript instanceof 運(yùn)算符深入剖析

代碼

1、完成如下代碼判斷一個(gè)變量是否是數(shù)字、字符串、布爾、函數(shù)

function isNumber(el){
    if( typeof el === "number" ){
        return ture;
  }else{
        return false;
  }
}
function isString(el){
  if( typeof el === "string" ){
        return ture;
  }else{
        return false;
  }
}
function isBoolean(el){
    if( typeof el === "boolean" ){
        return ture;
  }else{
        return false;
  }
}
function isFunction(el){
     if( typeof el === "function" ){
        return ture;
  }else{
        return false;
  }
}

var  a = 2,
      b = "zhouhuahua",
      c =false;
alert( isNumber(a) );
alert( isString(a) );
alert( isString(b) );
alert( isBoolean(c) );
alert( isFunction(a) );
alert( isFunction( isNumber ) );

2、以下代碼的輸出結(jié)果是?

console.log(1+1);   //2,兩個(gè)數(shù)相加,輸出數(shù)值;
console.log("2"+"4");  //"24",兩字符串拼接,輸出字符串;
console.log(2+"4");   //"24",一個(gè)數(shù)值和一個(gè)字符串相加,輸出字符串;
console.log(+new Date()); // 1471048600952,用new Date()參與計(jì)算會(huì)自動(dòng)轉(zhuǎn)換為從1970.1.1到現(xiàn)在的時(shí)間的毫秒數(shù)。
console.log(+"4");   // 4,在只有一個(gè)字符串時(shí),會(huì)嘗試將其轉(zhuǎn)換為數(shù)字;

在JavaScript中運(yùn)算符通常會(huì)根據(jù)需要對(duì)操作數(shù)進(jìn)行類型轉(zhuǎn)換,乘法操作符希望操作數(shù)是數(shù)字,但是 "3" * "5"也是合法的,JavaScript會(huì)自動(dòng)將其轉(zhuǎn)換為數(shù)字計(jì)算,返回Number 15;對(duì)減法也是一樣的。
不過有些操作符對(duì)不同的數(shù)據(jù)類型有不同的含義,比如 +:

  • 在兩個(gè)操作數(shù)都是數(shù)字的時(shí)候,會(huì)做加法運(yùn)算;
  • 兩個(gè)參數(shù)都是字符串或在有一個(gè)參數(shù)是字符串的情況下會(huì)把另外一個(gè)參數(shù)轉(zhuǎn)換為字符串做字符串拼接;
  • 在參數(shù)有對(duì)象的情況下會(huì)調(diào)用其valueOf或toString方法;
  • 在只有一個(gè)字符串參數(shù)的時(shí)候會(huì)嘗試將其轉(zhuǎn)換為數(shù)字;
  • 在只有一個(gè)數(shù)字參數(shù)的時(shí)候返回其正數(shù)值;


    加法操作符

3、以下代碼的輸出結(jié)果是?

var a = 1;
a+++a;

typeof a+2;

在a+++a表達(dá)式當(dāng)中,后置遞增的優(yōu)先級(jí)最高。所以相當(dāng)于(a++)+a。a一開始賦值為1,a++表示先賦值再自增,所以a++的計(jì)算結(jié)果為1,且此時(shí)a等于2。所以a+++a表達(dá)式的計(jì)算結(jié)果為3。
而typeof a+2中,typeof的優(yōu)先級(jí)比“+”高,所以它會(huì)先計(jì)算typeof a,得到的輸出是字符串"number"。然后是一個(gè)字符串加上一個(gè)數(shù)字,會(huì)把數(shù)字轉(zhuǎn)換成字符串。所以得到的輸出為"number2"的字符串。

優(yōu)先級(jí)

4、遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方

var arr =[3,4,5];
/* for(key in arr){
  console.log(arr[key]*arr[key]);
} */
for(i=0;i<arr.length;i++){
  console.log(arr[i]*arr[i]);
}
用for循環(huán)遍歷數(shù)組

5、遍歷JSON,打印里面的值

var obj = {
  name: "hunger",
  sex: "male",
  age: 28
}
for(k in obj){
  console.log( k+":"+obj[k] ) ;
}
用for-in語句遍歷對(duì)象屬性

6、下面代碼的輸出是?為什么

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

JavaScript引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,給他初始值undefined,然后再一行一行地運(yùn)行。這造成的結(jié)果,就是所有的變量的聲明語句,都會(huì)被提升到代碼的頭部,這就叫做變量提升。
上面的代碼相當(dāng)于如下代碼:

var a;
console.log(a); 
a = 1;
console.log(a); 
console.log(b); 
變量提升

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 什么是 JavaScript 語言? JavaScript 是一種輕量級(jí)的腳本語言。所謂“腳本語言”(script...
    oWSQo閱讀 1,818評(píng)論 0 1
  • 本章內(nèi)容 語法 數(shù)據(jù)類型 流控制語句 理解函數(shù) 3.1 語法 3.1.1 區(qū)分大小寫 區(qū)分大小寫 3.1.2 標(biāo)識(shí)...
    悶油瓶小張閱讀 735評(píng)論 0 0
  • 晚上閑來無事,收拾起了宿舍的書柜。一本本書整理起來,好像整理度過的這四年歲月,看到很多早已忘記的書又喚起了曾經(jīng)的記...
    你好我是有木閱讀 259評(píng)論 0 0
  • 1.1、IoC是什么 Ioc—Inversion of Control,即“控制反轉(zhuǎn)”,不是什么技術(shù),而是一種設(shè)計(jì)...
    維乾閱讀 429評(píng)論 0 1
  • 最近咳嗽的孩子特別多,和大家分享兩個(gè)穴位:揉肺俞,分推肩胛骨,咳嗽的克星,治各種咳嗽。 1、揉肺腧穴 手指放在肺俞...
    愛作夢(mèng)的魚兒閱讀 401評(píng)論 0 0