在學習廖雪峰前輩的JavaScript教程中,遇到了一些需要註意的點,因此作為學習筆記列出來,提醒自己註意! 如果大家有需要,歡迎訪問前輩的博客https://www.liaoxuefeng.com/學習。 比較運算符 當我們對Number作比較時,可以通過比較運算符得到一個布爾值,這是我們預期的結 ...
在學習廖雪峰前輩的JavaScript教程中,遇到了一些需要註意的點,因此作為學習筆記列出來,提醒自己註意!
如果大家有需要,歡迎訪問前輩的博客https://www.liaoxuefeng.com/學習。
比較運算符
當我們對Number作比較時,可以通過比較運算符得到一個布爾值,這是我們預期的結果:
2 > 5; // false 5 >= 2; // true 7 == 7; // true
實際上,JavaScript允許對任意數據類型做比較:
false == 0; // true false === 0; // false
要特別註意相等運算符==
。JavaScript在設計時,有兩種比較運算符:
第一種是==
比較,它會自動轉換數據類型再比較,很多時候,會得到非常詭異的結果;
第二種是===
比較,它不會自動轉換數據類型,如果數據類型不一致,返回false
,如果一致,再比較。
由於JavaScript這個設計缺陷,不要使用==
比較,始終堅持使用===
比較。
另一個例外是NaN
這個特殊的Number與所有其他值都不相等,包括它自己:
NaN === NaN; // false
唯一能判斷NaN
的方法是通過isNaN()
函數:
isNaN(NaN); // true
最後要註意浮點數的相等比較:
1 / 3 === (1 - 2 / 3); // false
這不是JavaScript的設計缺陷。浮點數在運算過程中會產生誤差,因為電腦無法精確表示無限迴圈小數。要比較兩個浮點數是否相等,只能計算它們之差的絕對值,看是否小於某個閾值:
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
null和undefined
null
表示一個“空”的值,它和0
以及空字元串''
不同,0
是一個數值,''
表示長度為0的字元串,而null
表示“空”。
在其他語言中,也有類似JavaScript的null
的表示,例如Java也用null
,Swift用nil
,Python用None
表示。但是,在JavaScript中,還有一個和null
類似的undefined
,它表示“未定義”。
JavaScript的設計者希望用null
表示一個空的值,而undefined
表示值未定義。事實證明,這並沒有什麼卵用,區分兩者的意義不大。大多數情況下,我們都應該用null
。undefined
僅僅在判斷函數參數是否傳遞的情況下有用。
數組
數組是一組按順序排列的集合,集合的每個值稱為元素。JavaScript的數組可以包括任意數據類型。例如:
[1, 2, 3.14, 'Hello', null, true];
上述數組包含6個元素。數組用[]
表示,元素之間用,
分隔。
另一種創建數組的方法是通過Array()
函數實現:
new Array(1, 2, 3); // 創建了數組[1, 2, 3]
然而,出於代碼的可讀性考慮,強烈建議直接使用[]
。
數組的元素可以通過索引來訪問。請註意,索引的起始值為0
:
var arr = [1, 2, 3.14, 'Hello', null, true]; arr[0]; // 返回索引為0的元素,即1 arr[5]; // 返回索引為5的元素,即true arr[6]; // 索引超出了範圍,返回undefined
對象
JavaScript的對象是一組由鍵-值組成的無序集合,例如:
var person = { name: 'Bob', age: 20, tags: ['js', 'web', 'mobile'], city: 'Beijing', hasCar: true, zipcode: null };
JavaScript對象的鍵都是字元串類型,值可以是任意數據類型。上述person
對象一共定義了6個鍵值對,其中每個鍵又稱為對象的屬性,例如,person
的name
屬性為'Bob'
,zipcode
屬性為null
。
要獲取一個對象的屬性,我們用對象變數.屬性名
的方式:
person.name; // 'Bob' person.zipcode; // null
變數
變數的概念基本上和初中代數的方程變數是一致的,只是在電腦程式中,變數不僅可以是數字,還可以是任意數據類型。
變數在JavaScript中就是用一個變數名錶示,變數名是大小寫英文、數字、$
和_
的組合,且不能用數字開頭。變數名也不能是JavaScript的關鍵字,如if
、while
等。申明一個變數用var
語句,比如:
var a; // 申明瞭變數a,此時a的值為undefined var $b = 1; // 申明瞭變數$b,同時給$b賦值,此時$b的值為1 var s_007 = '007'; // s_007是一個字元串 var Answer = true; // Answer是一個布爾值true var t = null; // t的值是null
變數名也可以用中文,但是,請不要給自己找麻煩。
在JavaScript中,使用等號=
對變數進行賦值。可以把任意數據類型賦值給變數,同一個變數可以反覆賦值,而且可以是不同類型的變數,但是要註意只能用var
申明一次,例如:
var a = 123; // a的值是整數123 a = 'ABC'; // a變為字元串
這種變數本身類型不固定的語言稱之為動態語言,與之對應的是靜態語言。靜態語言在定義變數時必須指定變數類型,如果賦值的時候類型不匹配,就會報錯。例如Java是靜態語言,賦值語句如下:
int a = 123; // a是整數類型變數,類型用int申明 a = "ABC"; // 錯誤:不能把字元串賦給整型變數
和靜態語言相比,動態語言更靈活,就是這個原因。
請不要把賦值語句的等號等同於數學的等號。比如下麵的代碼:
var x = 10; x = x + 2;
如果從數學上理解x = x + 2
那無論如何是不成立的,在程式中,賦值語句先計算右側的表達式x + 2
,得到結果12
,再賦給變數x
。由於x
之前的值是10
,重新賦值後,x
的值變成12
。
要顯示變數的內容,可以用console.log(x)
,打開Chrome的控制台就可以看到結果。
使用console.log()
代替alert()
的好處是可以避免彈出煩人的對話框。
strict模式
JavaScript在設計之初,為了方便初學者學習,並不強制要求用var
申明變數。這個設計錯誤帶來了嚴重的後果:如果一個變數沒有通過var
申明就被使用,那麼該變數就自動被申明為全局變數:
i = 10; // i現在是全局變數
在同一個頁面的不同的JavaScript文件中,如果都不用var
申明,恰好都使用了變數i
,將造成變數i
互相影響,產生難以調試的錯誤結果。
使用var
申明的變數則不是全局變數,它的範圍被限制在該變數被申明的函數體內(函數的概念將稍後講解),同名變數在不同的函數體內互不衝突。
為了修補JavaScript這一嚴重設計缺陷,ECMA在後續規範中推出了strict模式,在strict模式下運行的JavaScript代碼,強制通過var
申明變數,未使用var
申明變數就使用的,將導致運行錯誤。
啟用strict模式的方法是在JavaScript代碼的第一行寫上:
'use strict';
這是一個字元串,不支持strict模式的瀏覽器會把它當做一個字元串語句執行,支持strict模式的瀏覽器將開啟strict模式運行JavaScript。
來測試一下你的瀏覽器是否能支持strict模式:
'use strict'; // 如果瀏覽器支持strict模式, // 下麵的代碼將報ReferenceError錯誤: abc = 'Hello, world'; console.log(abc);
運行代碼,如果瀏覽器報錯,請修複後再運行。如果瀏覽器不報錯,說明你的瀏覽器太古老了,需要儘快升級。
不用var
申明的變數會被視為全局變數,為了避免這一缺陷,所有的JavaScript代碼都應該使用strict模式。我們在後面編寫的JavaScript代碼將全部採用strict模式。