JavaScirpt變量提升
兩個例子:
console.log(a);
var a = 1;
控制臺顯示:undefined
console.log(b);
b = 1;
控制臺顯示:ReferenceError: b is not defined
分析:
- JS里存在變量提升機(jī)制:即在JS代碼運(yùn)行之前會事前解析JS里的所有代碼,然后將聲明變量的語句放到最前面类浪,所以第一個例子中的
var a =1
;(效果等于var a ; a = 1;
)[var a;
]被提前解析到了前面载城,所以console.log(a);
語句執(zhí)行的時候,a=1;
這條語句由于不是變量的聲明(沒有var)所以沒有被執(zhí)行费就,所以此時變量a沒有被賦值诉瓦,所以console.log(a);
的結(jié)果為undefined.
- 在第二個例子中沒有var即沒有變量聲明的語句,所以沒有代碼被提前力细,這里的b不是一個變量睬澡,而是windows頂層對象的一個屬性,所以這個時候把b打印出來會報錯(即b沒有被定義)
JavaScript標(biāo)識符
第一個字母只能是Unicode字母(包括英文字母和其他語言的字母)或美元符號或者下劃線眠蚂,除此以外的字母可以是Unicode字母或美元符號或者下劃線和數(shù)字1~9.但是不能是關(guān)鍵字或者保留字煞聪。也不建議使用帶有特殊意義的單詞(NaN undefinded Infinity)
JavaScript注釋
要注意的是也會被視為單行注釋(因為JS歷史上兼容HTML的注釋)
都是注釋其之后的代碼塊 并且-->
只有放在行首才會被解析成注釋。放在其他位置的作用等于一元操作符++和大于符號>的組合逝慧。
JavaScript區(qū)塊
JavaScript使用大括號昔脯,將多個相關(guān)的語句組合在一起啄糙,稱為“區(qū)塊”(block)。
與大多數(shù)編程語言不一樣云稚,JavaScript的區(qū)塊不構(gòu)成單獨(dú)的作用域(scope)隧饼。也就是說,區(qū)塊中的變量與區(qū)塊外的變量静陈,屬于同一個作用域燕雁。
{
var a = 1;
}
a // 1
上面代碼在區(qū)塊內(nèi)部,聲明并賦值了變量a鲸拥,然后在區(qū)塊外部拐格,變量a依然有效,這說明區(qū)塊不構(gòu)成單獨(dú)的作用域刑赶,與不使用區(qū)塊的情況沒有任何區(qū)別捏浊。所以,單獨(dú)使用的區(qū)塊在JavaScript中意義不大角撞,很少出現(xiàn)呛伴。區(qū)塊往往用來構(gòu)成其他更復(fù)雜的語法結(jié)構(gòu),比如for谒所、if热康、while、function等劣领。
JavaScript switch
需要注意的是姐军,switch語句后面的表達(dá)式與case語句后面的表示式,在比較運(yùn)行結(jié)果時尖淘,采用的是嚴(yán)格相等運(yùn)算符(===)奕锌,而不是相等運(yùn)算符(==),這意味著比較時不會發(fā)生類型轉(zhuǎn)換村生。代碼如下
var x = 1;
switch (x) {
case true:
console.log('x發(fā)生類型轉(zhuǎn)換');
default:
console.log('x沒有發(fā)生類型轉(zhuǎn)換');
}
// x沒有發(fā)生類型轉(zhuǎn)換
JavaScript數(shù)值
表示方法:科學(xué)計數(shù)法 例:16e2(16*
10^2) 16e-2(16*
10^-2)
存在兩種情況惊暴,JS會自動將數(shù)值轉(zhuǎn)換成科學(xué)計數(shù)法
- 小數(shù)點(diǎn)前的數(shù)字多于21位。
- 小數(shù)點(diǎn)后的零多于5個趁桃。
數(shù)值的進(jìn)制
默認(rèn)情況下辽话,JavaScript內(nèi)部會自動將八進(jìn)制、十六進(jìn)制卫病、二進(jìn)制轉(zhuǎn)為十進(jìn)制油啤。下面是一些例子。
0xff // 255
0o377 // 255
0b11 // 3
特殊數(shù)值
1. 0和-0
幾乎所有場合0和-0都是等價的蟀苛,唯一有區(qū)別的場合是益咬,+0或-0當(dāng)作分母,返回的值是不相等的帜平。
(1 / +0) === (1 / -0) // false
2. NaN
1.NaN表示''非數(shù)字''(Not a Number)主要出現(xiàn)在將字符串解析成數(shù)字出錯的場合幽告。當(dāng)0除以0時梅鹦,也會出現(xiàn)NaN,0乘以Infinity评腺,也會返回NaN帘瞭;Infinity減去或除以Infinity,得到NaN蒿讥。
3.運(yùn)算規(guī)則
NaN與任何數(shù)(包括它自己)的運(yùn)算,得到的都是NaN抛腕。(NaN === NaN)返回的結(jié)果是false
4.判斷NaN的方法
isNaN方法可以用來判斷一個值是否為NaN.
但是芋绸,isNaN只對數(shù)值有效,如果傳入其他值担敌,會被先轉(zhuǎn)成數(shù)值摔敛。比如,傳入字符串的時候全封,字符串會被先轉(zhuǎn)成NaN马昙,所以最后返回true,這一點(diǎn)要特別引起注意刹悴。也就是說行楞,isNaN為true的值,有可能不是NaN土匀,而是一個字符串子房。
判斷NaN更可靠的方法是,利用NaN是JavaScript之中唯一不等于自身的值這個特點(diǎn)就轧,進(jìn)行判斷证杭。
function myIsNaN(value) {
return value !== value;
}
與數(shù)值相關(guān)的全局方法
parseInt()
parseInt方法用于將字符串轉(zhuǎn)為整數(shù)。如果字符串頭部有空格妒御,空格會被自動去除解愤。
如果parseInt的參數(shù)不是字符串(必須是合法的表達(dá)式),則會先轉(zhuǎn)為字符串再轉(zhuǎn)換乎莉。
parseInt(123aaa);
//Uncaught SyntaxError: Invalid or unexpected token
注意:這里傳入的參數(shù)會先進(jìn)行運(yùn)算送讲,但是123aaa是一個無效的表達(dá)式,所以程序不知道怎么轉(zhuǎn)化梦鉴。程序并不會聰明的以為你輸入是parseInt('123aaa');
字符串轉(zhuǎn)為整數(shù)的時候李茫,是一個個字符依次轉(zhuǎn)換,如果遇到不能轉(zhuǎn)為數(shù)字的字符肥橙,就不再進(jìn)行下去魄宏,返回已經(jīng)轉(zhuǎn)好的部分。
如果字符串的第一個字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號除外)存筏,返回NaN宠互。
字符串轉(zhuǎn)為整數(shù)的時候味榛,是一個個字符依次轉(zhuǎn)換,如果遇到不能轉(zhuǎn)為數(shù)字的字符予跌,就不再進(jìn)行下去搏色,返回已經(jīng)轉(zhuǎn)好的部分。
如果字符串的第一個字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號除外)券册,返回NaN频轿。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
上述第二行代碼由于無法解析小數(shù)點(diǎn)'.'所以返回NaN(反直覺 - -)
上述第三行代碼中傳入的參數(shù)為空字符串。效果等同于
parseInt();
需要注意的是在JS中parseInt方法和Number方法雖然都可以把傳入的參數(shù)轉(zhuǎn)化為數(shù)字烁焙,但是Number會把空字符串轉(zhuǎn)化成0航邢,而parseInt方法會把空字符串轉(zhuǎn)化成NaN上述第四行代碼中的'+'并不能轉(zhuǎn)化為數(shù)字所以是NaN但是第五行代碼中的+號屬于數(shù)字的正負(fù)號,這種情況除外骄蝇。
對于那些會自動轉(zhuǎn)為科學(xué)計數(shù)法的數(shù)字膳殷,parseInt會將科學(xué)計數(shù)法的表示方法視為字符串,因此導(dǎo)致一些奇怪的結(jié)果九火。
parseInt(1000000000000000000000.5) // 1
// 等同于
parseInt('1e+21') // 1
parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
5.進(jìn)制轉(zhuǎn)換parseInt方法還可以接受第二個參數(shù)(2到36之間)赚窃,表示被解析的值的進(jìn)制,返回該值對應(yīng)的十進(jìn)制數(shù)岔激。默認(rèn)情況下勒极,parseInt的第二個參數(shù)為10,即默認(rèn)是十進(jìn)制轉(zhuǎn)十進(jìn)制鹦倚。
parseFloat()方法
- .parseFloat方法用于將一個字符串轉(zhuǎn)為浮點(diǎn)數(shù)河质。
- 如果字符串符合科學(xué)計數(shù)法,則會進(jìn)行相應(yīng)的轉(zhuǎn)換震叙。
- 如果參數(shù)不是字符串掀鹅,或者字符串的第一個字符不能轉(zhuǎn)化為浮點(diǎn)數(shù),則返回NaN媒楼。
parseInt和parseFloat方法均在一種程度上不同于Number函數(shù)乐尊。
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
JavaScript字符串
- 如果要在單引號字符串的內(nèi)部,使用單引號(或者在雙引號字符串的內(nèi)部划址,使用雙引號)扔嵌,就必須在內(nèi)部的單引號(或者雙引號)前面加上反斜杠,用來轉(zhuǎn)義夺颤。
- 字符串默認(rèn)只能寫在一行內(nèi)痢缎,分成多行將會報錯。如果長字符串必須分成多行世澜,可以在每一行的尾部使用反斜杠独旷。(注意,反斜杠的后面必須是換行符,而不能有其他字符(比如空格)嵌洼,否則會報錯案疲。)
long
long
string";
longString
// "Long long long string"
##轉(zhuǎn)義
- 反斜杠(\)在字符串內(nèi)有特殊含義,用來表示一些特殊字符麻养,所以又稱為轉(zhuǎn)義符褐啡。
- 如果字符串的正常內(nèi)容之中,需要包含反斜杠鳖昌,則反斜杠前面需要再加一個反斜杠备畦,用來對自身轉(zhuǎn)義。
- 上面代碼中遗遵,a是一個正常字符萍恕,前面加反斜杠沒有特殊含義,反斜杠會被自動省略车要。
- 字符串可以被視為字符數(shù)組,因此可以使用數(shù)組的方括號運(yùn)算符崭倘,用來返回某個位置的字符(位置編號從0開始)翼岁,使用數(shù)組的length方法,用來返回字符串的長度司光。(但是實際上無法通過調(diào)用這兩種方法改變字符串的長度或者字符)
##Base64轉(zhuǎn)碼
JavaScript原生提供兩個Base64相關(guān)方法琅坡。
- atob():Base64編碼轉(zhuǎn)為原來的編碼
- btoa():字符串或二進(jìn)制值轉(zhuǎn)為Base64編碼
PS:這兩個方法不適合非ASCII碼的字符,會報錯残家。
btoa('你好')
// Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.