JavaScript基礎回顧一(型別、值和變數)
請看程式碼並思考輸出結果
var scope = 'global'; function f(){ console.log(scope); var scope = 'local'; console.log(scope); } f(); var a = []; console.log(a == 0,a == false); var b = [6]; console.log(b + 1,b-1); var c = {}; console.log(Boolean(c)==true);
對比答案
全部答對的同學,下文可不必閱讀,我相信你的基礎已經很紮實了^_^
沒有答對也不要灰心,本文會鞏固你的基礎知識,後續會有系列的基礎回顧知識,以饗諸君!
緣由
相信只要從事開發的同學,不論前端後端或多或少的使用過javascript這門語言。但對其深入理解的我相信並不在多數,我看過很多同學分享過的文章,說實話乾貨太少,自己的見解微乎其微,javascript基礎知識也很少能看到有文章寫到,萬丈高樓始於平地,基礎的重要性我一直認為不比前端框架低。主要來源於JS權威指南、網路資料以及自己的一些“偏見”。
資料型別
JavaScript兩大型別:原始型別和物件型別
原始型別(primitive type)
null
undefined
string
number
boolean
五大原始型別:其中 null、undefined都是其型別的唯一成員,boolean成員只有true和false,number型別即為數值(js均以浮點型表示),string即為字串型別(長度為16位),原始型別均為不可變型別,你無法改變數字1,也無法改變字串h,更不可能將false改變成其它值,只有物件型別可變
物件型別(object type)
物件型別是屬性的集合,大部分的物件都包含屬性名、屬性值(陣列物件可以看成為從0開始的有序屬性名),也就是名/值對,但函式是一個特殊的物件
常見的物件型別:
Array,Function,Math,Date,RegExp
型別轉換
值 | 轉換為字串 | 數字 | 布林值 | 物件 |
undefined | "undefined" | NaN | false | throws TypeError |
null | "null" | 0 | false | throws TypeError |
true | "true" | 1 | new Boolean(true) | |
false | "false" | 0 | new Boolean(false) | |
"" | 0 | false | new String(“”) | |
"1.1" | 1.1 | true | new String(“1.1”) | |
"ccy" | NaN | true | new String(“ccy”) | |
0 | "0" | false | new Number(0) | |
-0 | "0" | false | new Number(-0) | |
NaN | "NaN" | false | new Number(NaN) | |
Infinity | "Infinity " | true | new Number(Infinity) | |
-Infinity | "-Infinity " | true | new Number(-Infinity) | |
1 | "1" | true | new Number(1) | |
{} | 物件先轉換原始值,再有原始值進一步轉化 | 同左 | true | |
[] | 0 | true | ||
[6] | "6" | 6 | true | |
['a'] | 使用join()方法 | NaN | true | |
function(){} | "function(){}" | NaN | true |
JavaScript取值型別非常靈活,當期望使用一個布林值時,你可以提供任意型別值,JavaScript會根據需要自行轉換型別,字串和數字也同樣如此,原始型別的可通過對應的包裝類轉化成物件型別,具體轉化請熟悉上表。理解型別轉換,文章開頭關於a,b,c的輸出也就不在話下了。
變數宣告
ES5時代JavaScript還不支援塊級作用域,宣告變數採用關鍵字var
如下所示:
var i; var ccy,name;var m = 0, k = 1,n = 'bar';
var宣告的變數如果沒有賦予初始值,則預設為undefined,變數可為任意資料型別。
變數作用域
一個變數的作用域是程式原始碼中定義這個變數的區域。全域性變數擁有全域性作用於,在JavaScript中任何地方都是有定義的。然而在函式內宣告的變數只有在該函式體內有效,也就是區域性變數,函式引數也是區域性變數。
學過Java的同學應該知道就近原則的說法,類變數與方法中的變數同名時在該方法或者建構函式體內類變數是會被其覆蓋掉,JavaScript也遵循這一原則。
var關鍵字存在宣告提前的bug,在非嚴格模式下不會報錯。由此文章開頭關於方法的輸出等價於
function f(){ var scope; console.log(scope); var scope = 'local'; console.log(scope); }
理解變數宣告及作用域,文章開頭的輸出亦不在話下了。
作用域鏈
JavaScript是基於詞法作用域的語言,全域性變數在程式中始終有定義,區域性變數在宣告的函式題內以及其所巢狀的函式內始終是有定義的。
每段JavaScript程式碼都有一個與之關聯的作用域鏈(scope chain),這個作用域鏈是一個物件列表或連結串列,這組物件定義了這段程式碼的“作用域中”的變數,當需要查詢變數X的值時(變數解析),它會從鏈中的第一個物件開始查詢,若有則直接使用,若沒有則向上查詢,以此類推,若作用域鏈不存在X則丟擲ReferenceError異常。
希望本文能對您有所收穫,祝好!