Android開發(fā)學習JavaScript系列(二):變量和基本類型

有一種說法叫做“空杯理論”(就是那個著名的青年和禪師喝茶的故事),你學習一樣的新的語言時需要把之前你擅長的語言的知識忘掉,就像一個已注滿水的杯子,你只有把水倒掉才能重新裝水,清掉以前的知識(看法),你才能更好的接受新的知識(或者不容易授已有知識體系的限制)。

但其實人們在學習一種自己不知道的知識點時,會更需要一些合理的類比,將新的知識的相同和不同和已有的概念進行類比,這樣一個人可以更快的了解新的概念。我覺得我很難把已注滿水的杯子倒空,那我就先倒半杯吧。所以我之后的文章還是會有一些和Java類比的地方。

變量聲明

JavaScript使用var關鍵字進行變量的聲明,而且這個變量是沒有類型的,像Java這種變量具有數據類型的語言被稱為靜態(tài)數據類型語言,JavaScritp自然就可稱為動態(tài)數據類型語言了。如:

var foo;

因為沒有變量類型,所以對于同一個變量,既可以賦值為字符串,也可以賦值為數字。雖然說這并不是一個好習慣,在實際工作中也應該避免出現這樣的代碼。

var foo;
foo = "abs";
foo = 123;

和Java不同的還有,在聲明變量時,可以不需要關鍵字var,這樣的變量稱為隱式聲明變量。采用隱式聲明的變量都是全局變量,即使在函數內部隱式聲明的變量也屬于全局變量,這點要注意。相對于隱式聲明,在函數外部通過var聲明的變量也是全局變量。一般不推薦使用隱式聲明合局變量,而且在strict模式下,隱式聲明全局變量會報錯。

strict mode: ES5中引入“嚴格模式”,同正常模式相比,嚴格模式有很多行為上的不同。其中一個不同的行為就是嚴格模式禁止自動或隱式地創(chuàng)建全局變量。

常量聲明使用const。

ES6添加了一個新的關鍵詞:let。let與var一樣,也可以用來聲明變量,但它有著更好的作用域規(guī)則,let聲明的變量擁有塊級作用域。其實let這一點就和我們在Java的方法或者{}塊級作用域中聲明的變量一樣。

基本數據類型

在JavaScript中,有5種基本數據類型:

  • 字符串(string)
  • 數值(number)
  • 布爾(Boolean)
  • null
  • undefined

這5種基本數據類型之外都被稱為Object類型,可以使用內置的typeof函數判斷變量的類型。被聲明但未進行賦值的變量,其值為undefined。

** 字符串型**
和Java一樣,JavaScript的字符串型也是不可變類型,所以字符串值是不能改變的。使用“+”連接兩個字符串變量會生成一個新的字符串值。不過在JavaScript中,字符串型是一種內建類型,還存在一種字符串類(String,注意首字母大寫),相當于是string類型的包裝類,如Java中的int和Integer類的關系一樣。

字符串型可以使用兩種引號(單引號和雙引號)來包圍字符串字面量,這有一個好處就是可以通過兩種引號的靈活運用以減少轉義字符(\)的使用。

var hello = 'I say "yes"';
console.log(log);

還記得第一篇文章準備的運行環(huán)境嗎?大家可以把這后出現的代碼都在哪個環(huán)境下自己手寫運行一下,這個非常有必要!使用Chrome查看運行結果的話,修改了代碼再刷新一下瀏覽器即可。
輸出:

I say "yes"

字符串型(基本類型)和String類之間也同樣支持隱式類型轉換。

var s = '012';
console.log(s.length);

字符串對象可以使用new運算符顯式的生成:

var str = new String('abc');

字符串類型的比較
JavaScript有種相等的比較運算符:“==”和“===”,與之對應的判斷不相等的運算符為“!=”和“!==”。區(qū)別在于,“===”在比較時不會對數據類型進行轉換,稱為嚴格相等。如果我們只考慮字符串之間的比較,那么“==”和“===”的結果是沒有區(qū)別的。

var s1 = '012';
var s2 = '0';
var s3 = s2 + '12';
console.log(s1 == s3);
console.log(s1 === s3);

正如前面提到的,字符串型和字符串類是兩種類型,字符串型是基本類型,而字符串類屬于對象(Object)類型。所以在判斷兩者相等上是有差異的。

var s1 = new String('abc');
var s2 = new String('abc');
console.log(s1 == s2);
console.log(s1 === s2);

兩個結果都是“false”。所以想要比較兩個字符串對象的內容是否相等,需要進行一下類型轉換:

console.log(s1 + '' == s2);
"=="會進行隱式類型轉換,所以上面的s2對象也會被轉換成字符串型。對比結果為“true”。

** 數值型 **
在JavaScript中,數值的內部結構為64位的浮點小數。所以整數和浮點數在JavaScript的內部是一樣的,不存在類型轉換問題,對0做除法也不會得到錯誤的結果。

對于浮點數來說,基本上并不能正確表達一個數的值,大部份情況下只是表達一個近似值而已。

console.log(0.1 + 0.2);
console.log((0.1 + 0.2) == 0.3);

0.1 + 0.2得到的值是:0.30000000000000004。

正如存在字符串類(String類),JavaScript中也存在數值類(Number類)。

** NaN **
對NaN進行任何運算,其結果都是NaN。NaN的運算還具有更為特別的性質,NaN不但不與其他任何數值相等,就算是兩個NaN的值也是不相等的。也就是說我們不能用“==”來判斷一個值是否為NaN,在JavaScript中有一個全局函數isNaN,用來判斷值是否為NaN。

** 布爾型 **
這個可以省略先,用你知道的Java的相關布爾型的知識已足夠。

** null型 **
null值的含義為沒有引用任何對象,對null值進行typeof運算得到的結果是“object”。因此,其他類型的數據都可以通過typeof運算來進行類型判斷,但對于null型來說,就必須通過和null值的等值判斷才能確定。

console.log(typeof null);

null沒有與之相對應的Null類,所以“null.toString()”這樣的代碼是會產生TypeError異常:

test.html:14 Uncaught TypeError: Cannot read property 'toString' of null

** undefined型 **
從字面意思來看,undefined值似乎和null值是一樣的,但實際上,undefined并非字面量,而是一個預定義的全局變量。

undefined = 'abc';
console.log(undefined);

也就是說我們給undefined重新賦值并不會報錯,只是因為在ES5版中undefined變?yōu)榱酥蛔x變量,所以我們賦值沒有什么效果,上面的輸出還是“undfined”。

與null的值區(qū)別:null值指的是沒有引用任何對象,而undefined指的是一個尚未定義的值。要使一個變量的值為null,必須將null以字面量的形式賦值給訪變量。

var s;
console.log(typeof s);

除了基本類型之外,其他的所有類型都是Object類型,不過JavaScript還有一種函數(Function)的類型,可以將其理解為Object類型里的一種特別類型,或者簡單說函數也是一種對象。這也是JavaScript和Java中的函數最大的不同。

function f() {}
console.log(typeof f);

結果會顯示“function”。

最后

好像已經夠長的了,再寫很多人就要打瞌睡了,只能:未完待續(xù)......

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

推薦閱讀更多精彩內容