Day1:JavaScript變量與類型

1.JavaScript變量

變量(Variables)在程序中用于存儲數(shù)據(jù),我們可以將數(shù)據(jù)存入變量,并在將來替換變量中保存的數(shù)據(jù),或是銷毀變量。

在js中,使用var關(guān)鍵字來聲明變量(//是單行注釋符號,//之后的在同一行的內(nèi)容不會被運(yùn)行,此外/* */符號表示塊注釋,用于注釋多行代碼):

var a;  // 聲明變量a,此時變量的值為undefined
var b, c; // 聲明變量b和變量c,這兩個變量的值都為undefined
var d = 0; // 聲明變量d,并將d賦值為0
var e, f = 1; // 聲明變量e和f,其中e的值為undefined,f的值為1

分號作為js表達(dá)式的分隔符,是可以省略的,一般不推薦省略

變量的賦值

使用如下方法為變量賦值(存入或替換數(shù)據(jù)):

var a = 0; // 聲明變量a并賦值為0
a = 1; // 將變量a重新賦值為1

let和const關(guān)鍵字

在ES6標(biāo)準(zhǔn)中,新增了letconst關(guān)鍵字,let的語法與var一致,但使用let聲明的變量,只在let命令所在的塊中有效,我們把這個有效區(qū)域稱為塊作用域

{
  let a = 0;
  var b = 0;
  a // a is 0
  b // b is 0
}
a // a is undefined
b // b is 0

let命令也不允許在同一個作用域內(nèi)重復(fù)聲明:

let a = 0;
let a = 1; // error
let b = 1; // correct
{
  let a = 2; // correct
  let a = 3; // error
}

const關(guān)鍵字用于聲明一個常量,一旦常量被聲明,常量中存儲的數(shù)據(jù)就不可以被修改。我們可以把常量理解為一個不允許修改內(nèi)容的變量:

const a = 0;
a = 1 // error

使用const關(guān)鍵字聲明常量,必須在聲明時給常量賦值:

const a; // error

變量命名規(guī)則

js中的變量有嚴(yán)格的命名規(guī)則:

  1. 變量名不允許以數(shù)字開頭,但數(shù)字可以被用在變量中,例如:3xxx12xxx,這些是錯誤的變量名稱,a1a2b,這些是正確的名稱;
  2. 數(shù)學(xué)或者邏輯操作符(運(yùn)算符)不允許出現(xiàn)在變量名中,例如:a-b,a|b,a*b,這些是錯誤的;
  3. 除了下劃線,任何標(biāo)點(diǎn)符號都不允許出現(xiàn)在變量名中,例如:a:b,a#b是錯誤的,a_b_ab是正確的;
  4. 空格不允許使用,變量名中不允許換行;
  5. 保留字關(guān)鍵字不允許用作變量名,例如:class,string是錯誤的,klassstr是正確的;
  6. 變量名是大小寫敏感的,例如:aA是兩個截然不同的變量;

?? 實(shí)際上,符合js標(biāo)識符規(guī)則的unicode字符都可以作為標(biāo)識符,基于上述規(guī)則,我們應(yīng)該可以知道,>
以下變量名都是合法的:$hello,hello$,你好?_?巴扎嘿123
?? 實(shí)際使用中,不建議將中文字符特殊符號作為變量名使用。

命名規(guī)范

js變量名應(yīng)該語義化,即根據(jù)功能來命名,看到變量名稱,基本就可以猜到變量的用途,常用的命名規(guī)范有三種:
?? 駝峰命名法:
這是js中最普遍使用的命名規(guī)范,駝峰命名法分為兩種:

  1. 小駝峰命名法
    用多個單詞書寫變量名時,首詞的首字母小寫,后面所有單詞的首字母大寫,例:doLogin,setFirstName。
  2. 大駝峰命名法
    用多個單詞書寫變量名時,所有單詞的首字母全部大寫,這種命名方式常用在js的構(gòu)造函數(shù)中,例:UserInfoSafeCenter

匈牙利命名法:
變量名 = 數(shù)據(jù)類型 + 描述
例如:

let sName = "HanMeiMei"; // s表示字符串類型string
let iPrice = 100; // i表示整型數(shù)字類型number(int)

帕斯卡命名法:
這種命名法即大駝峰命名法。


其他:
有些程序中推薦使用-或者_符號連接單詞,例如:first-name,delete_article,這種命名法常用在c/c++程序中。


2.JavaScript數(shù)據(jù)類型

動態(tài)類型與弱類型

js是一種動態(tài)類型、弱類型的腳本語言。
在聲明變量時,不需要為變量指定類型,js將會自動給變量指定類型,我們也可以將另一種類型的值直接賦值給已有的變量,這種類型被稱為動態(tài)類型

let a = 0 // 此時變量a保存的值是數(shù)字類型
a = "hello" // 允許直接將字符串類型的值賦值給變量a

在使用變量運(yùn)算時,程序能夠“容忍”類型的隱式自動轉(zhuǎn)換,這種特性被稱為弱類型

let a = "hello"; // a是字符串string類型
let  b = 1; // b是數(shù)字number類型
let c = a + b; // 結(jié)果為"hello1",js自動將加號左邊的數(shù)字轉(zhuǎn)換為字符串進(jìn)行運(yùn)算,結(jié)果為兩個字符串的拼接

原始類型與對象類型

js中的數(shù)據(jù)類型可以概括為以下幾種:

  • 6種原始類型(原始類型也稱為基本類型)
    • Number 數(shù)字型
    • String 字符串型
    • Boolean 布爾型
    • Undefind 未聲明(轉(zhuǎn)為數(shù)字時為NaN)
    • Null 空值(轉(zhuǎn)為數(shù)字時為0)
    • Symbol 符號類型
  • 1種對象類型
    • Object 對象

Number類型

js的數(shù)字類型不區(qū)分精度,它只有一種類型:基于 IEEE 754 標(biāo)準(zhǔn)的雙精度 64 位二進(jìn)制格式的值(-(2^63 -1) 到 2^63 -1),js也沒有為整數(shù)規(guī)定一種特殊類型。
除了整數(shù)、浮點(diǎn)數(shù)(小數(shù))外,還有一些其他的數(shù)字:+Infinity正無窮大-Infinity負(fù)無窮大,NaN (not a number 非數(shù)值)

拓展
在ES6標(biāo)準(zhǔn)中,允許使用Number.MAX_SAFE_INTEGER方法檢查數(shù)字是否在允許的范圍內(nèi)
在ES6中,也可以用Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER表示js能夠表示的最大和最小數(shù)字

js中,用+number表示正數(shù),+符號可以省略,例如:+5,5;
-number表示負(fù)數(shù),例如:-5
0也可以用-0或者+0表示,如果用一個數(shù)字除以0,將會得到無窮大:

12 / -0 = -Infinity
12 / +0 = +Infinity

將數(shù)字賦值給變量:

let a = 12;
let b = 3.14;
let c = -1;

String類型

字符串類型用于表示文本。js的字符串用單引號或者雙引號表示:

let a = 'hello world';
let b = '123'; // 這里的'123'是一個字符串,它不能直接做四則運(yùn)算

字符串的長度是指字符串中字符的個數(shù),用string.length來表示一個字符串的長度:

let str = 'hello world!';
console.log(str.length); // 12

拓展:瀏覽器控制臺中調(diào)試時,如需查看變量,不需要輸入console.log命令,直接輸入變量名后回車即可

使用字符串時,一定要注意為字符串加上引號,變量和字符串的顯著區(qū)別,在于變量沒有引號,而字符串有引號!

Boolean 布爾型

布爾型表示邏輯中的正反兩個方面,布爾類型有兩個值:truefalse。

Undefined

如果定義了一個變量但沒有給它賦值,那么它的值是undefined,注意區(qū)分大小寫。

拓展1:一個函數(shù)如果沒有返回值,那么它將返回undefined
拓展2:在局部作用域中,undefined允許被用作變量名,但是永遠(yuǎn)不要這樣做

Null

空類型的值只能是null,表示一個東西就是“空”這個狀態(tài),注意區(qū)分大小寫:

let box = null // 空值,盒子里什么也沒有,是空的
let bag;
console.log(bag) // undefined, bag被定義而沒有賦值

Symbol類型*

Symbol類型用于表示一個獨(dú)一無二的值,Symbol類型一般用作對象的屬性名:

let sym1 = Symbol('a');
let sym2 = Symbol('a');
console.log(sym1 == sym2) // false,比較兩個symbol的值,得到false

Object

對象類型較為復(fù)雜,在以后的教程中會逐一詳細(xì)介紹。
js的對象有屬性方法兩種成員,對對象的屬性進(jìn)行查看、修改等操作,稱為對屬性的訪問,使用對象的方法,稱為對方法的執(zhí)行調(diào)用,用點(diǎn)號.來訪問屬性和執(zhí)行方法:

語法
Object.property // 訪問屬性
Object.function() // 調(diào)用方法

例:

/* 用花括號來表示一個對象,屬性和方法可以自行規(guī)定,成員(屬性和方法)之間用逗號做分隔 */
let 對象名(變量名) = {
  屬性1: 屬性值,
  屬性2: 屬性值,
  方法名() {
    方法體;
  }
};

let student = {  // 定義student對象
  name: '小明', // student對象的name屬性,值為字符串“小明”
  age: 18, // student對象的age屬性,值為數(shù)字18
  // student對象的goToKlass方法,執(zhí)行方法會在控制臺輸出字符串,class是js的保留字,為了避免誤用做標(biāo)識符,常將class寫作klass
  goToKlass() { 
    console.log('去上課');
  }
};
console.log(student.name); // "小明",打?。ㄔL問)name屬性
student.age = 20; // 修改age屬性
console.log(student.age); // 20
student.goToKlass(); // "去上課",調(diào)用goToKlass方法

js中一切皆對象,這句話不是指一切都是對象類型,而是處理數(shù)據(jù)時可以把數(shù)據(jù)看作對象,js會自動為一些內(nèi)容添加屬性和方法,例如:

let name = 'xiaoming';
let r1 = name.length; 
console.log(r1) // 8, 字符串有l(wèi)ength屬性,表示字符串的長度
let price = 6.9855;
let r2 = price.toFixed(2); 
console.log(r2); // 字符串"6.99", Number.toFixed(n)方法將數(shù)字轉(zhuǎn)換為字符串,并四舍五入保留n位小數(shù)

拓展:訪問字符串的屬性時,js臨時創(chuàng)建一個對象,臨時對象的屬性只可讀,不可寫,訪問結(jié)束后,臨時對象即被銷毀,這讓字符串或數(shù)字類型的數(shù)據(jù)看起來也像一個對象,因此“一切皆對象”。

3.類型判斷

typeof操作符

使用typeof操作符來判斷數(shù)據(jù)類型,這個運(yùn)算返回一個表示類型的字符串

let a = 'hello';
typeof a; // 'string'
typeof 321; // 'number'
typeof(321); // 'nunber'
typeof undefined; // 'undefined'
typeof {a: 1}; // 'object'

特殊情況

有些時候,typeof判斷出的類型不能“想當(dāng)然”,以下例子中沒有出現(xiàn)過的形式,在后面的課程中會介紹:

typeof null; // 'object'
typeof function( ){ } // 'function',即便函數(shù)屬于對象類型,typeof會返回'function'
let str = new String('hello');
let num = new Number(123);
typeof str; // 'object'
typeof num; // 'object',new關(guān)鍵字實(shí)例化(可以理解為創(chuàng)建)一個對象

補(bǔ)充:正則表達(dá)式的類型在瀏覽器中使用typeof檢測時有時是function,有時是object,這取決于運(yùn)行js的瀏覽器,即js的宿主,在當(dāng)前(2017.9)最新版本的chrome和firefox瀏覽器中,正則表達(dá)式的類型均為object

4. 運(yùn)算操作符

n元操作符

n表示有n個操作數(shù)參與運(yùn)算操作,js中有一元操作符和二元操作符,還有一個特殊三元操作符。

一元操作符: 操作符 操作數(shù)1 |或| 操作數(shù) 操作符

二元操作符: 操作數(shù)1 操作符 操作數(shù)2

三元操作符: 操作數(shù)1 操作符 操作數(shù)2 操作符 操作數(shù)3

算數(shù)運(yùn)算符

算數(shù)運(yùn)算符有加減乘除四則運(yùn)算、求余、自增自減和-、+,下表的=符號不表示賦值:

表達(dá)式 示例 說明
a + b 1 + 2 = 3 加法
a - b 1 - 2 = -1 減法
a * b 3 * 7 = 21 乘法
a / b 6 / 2 = 3 除法
a % b 5 % 2 = 1 求余
a++++a 5++ = 6 自增
a--,--a 5-- = 4 自減
-a -5 = -5 取反
+a +'8' = 8 將非數(shù)字轉(zhuǎn)換為數(shù)字

++--操作符
當(dāng)把操作符放在前面時,返回加1后的操作數(shù),例如:let a = 1; console.log(++a);,結(jié)果為2,a在運(yùn)算結(jié)束后也為2
當(dāng)把操作符放在后面時,先返回原操作數(shù),然后再將操作數(shù)加1:let a = 1; console.log(a++);,結(jié)果為1,a在運(yùn)算結(jié)束后值為2

+操作符
+操作符不僅僅表示數(shù)學(xué)運(yùn)算的相加,當(dāng)把+ 操作符用在字符串中時,表示兩個字符串的連接:
'hello' + 'world' 結(jié)果為 'helloworld'

賦值運(yùn)算符

賦值運(yùn)算符將右邊的操作數(shù)賦值給左邊的操作數(shù),最常用的賦值運(yùn)算符是等于=符號,也有一些復(fù)合型的賦值運(yùn)算符:

x = y // 把y的值賦值給x
x += y // 相當(dāng)于 x = x + y('='符號的運(yùn)算優(yōu)先級很低,放在后面計算)
x -= y // x =  x - y(注意x與y的順序)
x /= y // x = x / y
x %= y // x = x % y
// 這里只列舉常用的表達(dá)式,不包含完整的賦值運(yùn)算操作符

比較運(yùn)算符

比較運(yùn)算符用于邏輯比較,返回truefalse

表達(dá)式 示例 說明
a == b 1 == 2 false,等于時返回true
a != b 1 != 2 true,不等于時返回true
a === b 1 === '1' false,全等于,數(shù)值和類型都相等時返回true
a !== b 6 !== 2 true,不全等于,數(shù)值或類型不等時返回true
a > b 5 > 2 true,左側(cè)大于右側(cè)時返回true
a < b 5 < 6 true,左側(cè)小于右側(cè)時返回true
a <= b 5 <= 4 false,左側(cè)小于等于右側(cè)時返回true
a >= b -5 >= -5 true,左側(cè)大于等于右側(cè)時返回true

邏輯運(yùn)算符

與、或、非運(yùn)算,是最常見的邏輯運(yùn)算,當(dāng)操作數(shù)都是布爾值時,邏輯運(yùn)算的返回值也是布爾值,當(dāng)邏輯運(yùn)算符不是布爾值時,可能返回其他類型的值(示例中提到的轉(zhuǎn)換,在本篇教程的后續(xù)部分會講到):

表達(dá)式 示例 說明
a && b exp1 && exp2 邏輯與,如果exp1能被轉(zhuǎn)換為false,則返回exp1,否則返回exp2;兩邊都是true時,返回true,否則返回false
a || b exp1 || exp2 邏輯或,如果exp1能被轉(zhuǎn)換為true,則返回exp2,否則返回exp1;兩邊只要有任意一個是true時,返回true,否則返回false
!a !exp 邏輯非,如果exp能被轉(zhuǎn)換為true,則返回false,否則返回true(邏輯取反)

在js中,null0,""(空字符串),NaNundefined能夠被轉(zhuǎn)換為false,簡單地記憶為“非零非空即是true”


拓展:邏輯短路
上述的邏輯與邏輯或短路的特性,即:無論運(yùn)算是否完全結(jié)束,如果當(dāng)前的運(yùn)算足夠得出最終的結(jié)果時,則后續(xù)的運(yùn)算立刻停止,并立刻返回最終結(jié)果,例:

let x = 5;
(x > 0) || (x++); //這里返回true
console.log(x); // x為5,不為6

由于x>0已經(jīng)足夠得出true這個結(jié)果,因此右邊的表達(dá)式并沒有運(yùn)算。

  • 邏輯與運(yùn)算可以簡單記憶為:兩端都為true時返回true,否則返回false;
  • 邏輯或運(yùn)算可以簡單記憶為:有任意一端為true時返回true,兩端都為false時返回false。

以下是一些邏輯運(yùn)算示例:

true && true // true
true || false // true
3 && 2 // 2
0 && 2 // 0
'' && 2 // '',引號內(nèi)不寫內(nèi)容,表示空字符串
6 || 5 // 6
0 || 6 // 6
5 > 0 || 5 < 0 // true
false || 5 // 5
true && 3 // 3
!'hello' // false

移位運(yùn)算符

表達(dá)式 示例 說明
a << n 8 << 1 16,左移位,8的二進(jìn)制是1000,左移1位變?yōu)?0000,換算為十進(jìn)制得16
a >> n 9 >> 2 2,右移位,9的二進(jìn)制是1001,右移2位為10(多余位舍棄),換算為十進(jìn)制得2
a >>> n 8 >>> 2 2,補(bǔ)零右移,這個運(yùn)算會將左邊空缺的位置用0補(bǔ)齊,8的二進(jìn)制是1000,補(bǔ)零右移兩位是0010,換算為十進(jìn)制得2

對于非小數(shù)來說,a << n的左移運(yùn)算相當(dāng)于a*2^n
相應(yīng)的,a >> m的右移運(yùn)算相當(dāng)于a*2^-m。

位邏輯運(yùn)算符

表達(dá)式 示例 說明
a & b 3 & 2 2,按位與,在a與b的位表示中,每個對應(yīng)的位都為1時返回1,否則返回0
a | b 5 | 6 7,按位或,在a與b的位表示中,每個對應(yīng)的位只要有一個為1,就返回1,否則返回0
~a ~3 -4,按位非,對操作數(shù)的各個位取反

以計算5 | 6為例,先將操作數(shù)轉(zhuǎn)換為32位的整數(shù),如果位數(shù)不夠,則取低32位(低位指從右往左數(shù)32位),然后再將對應(yīng)位兩兩比較:
5:0000 0000 0000 0000, 0000 0000 0000 0101
6:0000 0000 0000 0000, 0000 0000 0000 0110
r: 0000 0000 0000 0000, 0000 0000 0000 0111
因此最終結(jié)果為7
對于~3這個表達(dá)式,由于按位非將所有位全部取反,左側(cè)第一位表示符號位,當(dāng)?shù)谝晃皇?時表示負(fù)數(shù),因此最終結(jié)果為-4(二進(jìn)制計算的結(jié)果是負(fù)數(shù)的補(bǔ)碼表示法)

提示:位運(yùn)算的運(yùn)算效率比其他運(yùn)算更高

條件運(yùn)算符(三元)

語法
條件 ? 值1 : 值2

如果條件為true,則運(yùn)算結(jié)果取值1,否則取值2,值1和值2也可以是表達(dá)式,例:

let group = (age > 16) ? 'children' : 'young'; //當(dāng)年齡大于16時,group的值為'young',否則為'children'

5.運(yùn)算時的類型轉(zhuǎn)換

字符串轉(zhuǎn)數(shù)字

parseInt()parseFloat()方法分別將字符串轉(zhuǎn)換為整數(shù)和浮點(diǎn)數(shù),這兩個方法返回一個新的值,而不是修改被轉(zhuǎn)換的值:

parseInt('3.14'); // 3,字符串轉(zhuǎn)換為整數(shù)
parseFloat('3.14'); // 3.14,字符串轉(zhuǎn)換為浮點(diǎn)數(shù)
parseInt('1f', 16); // 31,后面的16表示十六進(jìn)制(以16為基數(shù)),運(yùn)算結(jié)果為十進(jìn)制16+15=31

自動類型轉(zhuǎn)換

將不同的類型做運(yùn)算時,js會臨時將數(shù)值進(jìn)行類型轉(zhuǎn)換,以下列舉部分轉(zhuǎn)換規(guī)則:

  • 字符串與數(shù)字相加,數(shù)字轉(zhuǎn)型為字符串:'hello' + 123 // 'hello123'
  • 布爾與數(shù)字相加,布爾轉(zhuǎn)型為數(shù)字,true對應(yīng)1,false對應(yīng)0:true + 1 // 2
  • 布爾與字符串相加,布爾轉(zhuǎn)型為字符串:true + hello // 'truehello'

擴(kuò)展:快速轉(zhuǎn)換字符串和數(shù)字
字符串轉(zhuǎn)數(shù)字:+String,在字符串前添加+符號可以快速將字符串轉(zhuǎn)換為數(shù)字
數(shù)字轉(zhuǎn)字符串:'' + NumberNumber + '',數(shù)字加空字符串可以得到一個與數(shù)字值相等的字符串

6.運(yùn)算符優(yōu)先級

四則運(yùn)算中,乘除法比加減法的優(yōu)先級更高(與我們的常識相同),連續(xù)做加法時,從左往右計算,千萬不可以隨意使用數(shù)學(xué)中的結(jié)合律運(yùn)算:

'hello' + 1 + 2 // 結(jié)果為'hello12',不能先計算后面的1+2

運(yùn)算符的優(yōu)先級從高到低如下所示,高優(yōu)先級的符號優(yōu)先計算:

  1. 圓括號
  2. 后置自增自減(a++)
  3. 邏輯非, 按位非
  4. 一元加減法(+a, -b),前置自增自減,typeof
  5. 乘除法,求余
  6. 加減法
  7. 移位
  8. 大小比較,大于等于,小于等于
  9. 等于,全等于,不等于,不全等于
  10. 按位與
  11. 按位或
  12. 邏輯與
  13. 邏輯或
  14. 條件運(yùn)算
  15. 賦值運(yùn)算
  16. 逗號

本系列教程作品采用 [知識共享署名-非商業(yè)性使用-禁止演繹 4.0 國際許可協(xié)議] 進(jìn)行許可。 轉(zhuǎn)載請發(fā)郵件到我的郵箱340349237@qq.com,并注明作者Tianzhen。

練習(xí):Day1.5:鞏固練習(xí)
下一篇:Day2:字符串與數(shù)組

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

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