JavaScript總結1

詞法結構

1. JavaScript程序是用Unicode字符集編寫的.javascript

let s = '你好'
// true
console.log(s === '你好')
// 你好
console.log(s)

2. JavaScript區分大小寫, 而HTML不區分大小寫.(我的推薦命名JS變量, 使用駝峯式命名)java

3. JavaScript會忽略程序中標識之間的空格, 可是良好的代碼風格相當重要.web

4. JavaScript支持"//"和/*...*/兩種註釋, 可是註釋中不可嵌套註釋.正則表達式

5. 直接量: 程序中直接使用的數據值, 可簡單理解爲"直接分配內存地址的變量", 例如數值, 字符串, 布爾型和正則表達式直接量(/javascript/gi).數組

6. JavaScript的標識符必須以字母, 下劃線或者美圓符號開始, 後續跟字母, 數字, 下劃線或者美圓符號.函數

7. JavaScript中關於填補分號的規則: 只要在缺乏了分號就沒法正確解析代碼的時候, JavaScript纔會填補分號. 我的習慣爲不加分號(在ES6的語法下)spa

 

類型, 值和變量

概述

JavaScript的數據類型分爲兩類: 原始類型和對象類型. JavaScript的原始類型包括數字, 字符串和布爾值. 而對象是屬性的集合, 每一個屬性都由"名/值對"組成.指針

    咱們一般會判斷一個變量是否爲數字,字符串,布爾值, 函數或者對象. 最簡單的一個方法是使用typeof:code

// "number"
console.log(typeof 1)
// "string"
console.log(typeof 'hello')
const f = () => {}
// function
console.log(typeof f)
// object
console.log(typeof [])

但使用typeof沒法判斷數組, 這時候咱們須要使用Array.isArray:對象

// true
console.log(Array.isArray([]))

    存在一種特殊的狀況, 不管傳進來的參數是什麼, 咱們須要的是一個數值. 這時候通常使用parseInt/parseFloat進行轉換後, 不可以使用typeof來判斷(typeof NaN === "number"), 應該使用isNaN()來判斷是否爲NaN.

 

    而針對對象, 因爲是無序哈希集合, 則工做中常常會碰到以下狀況:

1) 獲取全部的keys: 使用Object.keys():

const dst = {
    name: 'xx',
    age: 33,
}
// ['name', 'age']
console.log(Object.keys(dst))

2) 對對象進行遍歷, 可以使用in, 若是須要對可迭代對象進行變量, 則須要使用of:

function* foo() {
    yield 1
    yield 2
}
let f = foo()
// 1
// 2
for (let k of f) {
    console.log(k)
}

3) 對一個變量進行深層次的獲取, 可能會寫出這樣的代碼:

dst.country && dst.country.province && dst.country.province.name

    這時候, 要麼定義一個函數來獲取, 要麼須要一層層判斷.

 

JavaScript中有兩個特殊的原始值: null和undefined, 它們不是數字,字符串和布爾值. 它們一般分別表明了各自特殊類型的惟一的成員.原始類型, null和undefined均爲不可變類型.

    針對null和undefined, 存在以下的坑:

let a = undefined
let b = null
a = a + ''
b = b + ''
// string undefined
console.log(typeof a, a)
// string null
console.log(typeof b, b)

    這可能並不是咱們的本意. 實際項目中不多會糾結於null/undefined, 通常將它們當作false便可.

 

數組是特殊的集合, 它的下標索引即爲key值, 而對象的key爲字符串.

let arr = [11, 22, 33]
// 0 -- 11
// 1 -- 22
// 2 -- 33
for (let k in arr) {
    console.log(k, '--', arr[k])
}
// true
console.log(arr['1'] === arr[1])

 

函數是對象, 而箭頭函數的引入, 則方便了函數做爲參數進行使用:

const f1 = (num) => ++num
const f2 = (num) => () => f1(num)

// 2
console.log(f2(1)())

 

JavaScript解釋器有本身的內存管理機制, 能夠自動對內存進行垃圾回收.

ES6中引入塊級做用域, 儘可能使用let/const, 放棄var.

數字

  1. JavaScript不區分整數值和浮點數值, 全部數字均以浮點數值表示.
  2. JavaScript中除以0並不報錯, 只是返回無窮大(Infinity)/負無窮大(-Infinity). 而0 / 0是沒有任何意義的, 因此用NaN表示(NaN表明非數字, 可用isNaN()判斷, 例如isNaN("hello")爲true).
  3. JavaScript中浮點數依舊存在精度問題:
let x = 0.3 - 0.2
let y = 0.2 - 0.1
x == y -->false
x == 0.1-->false
y == 0.1-->true

文本

字符串的使用

let s = "hello world"

s.charAt(0) ==> "h": 第一個字符

s.charAt(s.length - 1) ==> "d": 最後一個字符

s.substring(1, 4) ==> "ell": 第2~4個字符

s.slice(1, 4) ==> "ell": 同上

s.slice(-3) ==> "rld": 最後三個字符

s.indexOf("l") ==> 2: 字符l首次出現的位置

s.lastIndexOf("l") ==> 9: 字符l最後出現的位置

s.indexOf("l", 3) ==> 3: 在位置3及以後首次出現字符l的位置.

s.split(" ") ==> ["hello", "world"]: 分割字符串

s.replace("h", "H") ==> "Hello world": 替換

s.toUpperCase() ==> "HELLO WORLD": 轉換成大寫

布爾值

轉換爲false的變量: undefined, null, NaN, 0, -0, ""

    在工做中, 常常犯以下的錯誤, 例如判斷一個變量是否爲false:

if (a) {}

但有時候沒考慮到a爲空數組/空對象的狀況. 因此, 針對數組來講, 應該這樣判斷:

if (Array.isArray(a) && a.length === 0) {}

但空對象並很差判斷, 若是咱們僅僅判斷:

if (typeof a === 'object' && Object.keys(a).length === 0) {}

須要考慮到萬一a繼承了某個類的屬性怎麼辦? 因此更好的方法應該判斷某個屬性是否在a中:

if ('name' in a) {}

 

null和undefined

null表明空指針, 一般用來表示數字, 字符串和對象的"無值狀態"

undefined表明未初始化.

全局對象

全局屬性: 好比undefined, Infinity和NaN

全局函數: 好比isNaN(), parseInt()和eval()

構造函數: 好比Date(), RegExp(), String(), Object()和Array()

全局對象: 好比Math和JSON

包裝對象

對於字符串, 如下代碼是正確的:

let s = "hello world"

let word = s.substring(1, 4)

既然字符串不是對象, 它爲何會有substring方法呢? 由於引用字符串s的屬性, JavaScript就會將字符串經過調用new String(s)的方式裝換成對象, 一旦屬性引用結束, 這個新建立的對象就會銷燬(同理於Number()和Boolean()):

let s = "test"

s.len = 4

let t = s.len

t ==> undefined

而:

"hello" == new String("hello") ==> true

"hello" === new String("hello") ==> false

不可變的原始值和可變的對象引用

原始值: undefined, null, 數字, 布爾值, 字符串. 它們均不可改變.

對象: 數組和函數, 可改變.

比較兩個變量, 除非特地, 不然儘可能使用"==="來進行比較. 而對象的比較毫無心義.

let a = 1
let b = '1'
// true
console.log(a == b)
// false
console.log(a === b)

對象的引用是一個大問題, 例如咱們可能會寫以下的代碼:

let arr = [1, 2]
let b = arr
b.push(3)
// [1, 2, 3]
console.log(arr)

    咱們須要的是一個副本, 而非引用. 這時候, 應該使用Object.assign:

let arr = [1, 2]
let b = Object.assign([], arr)
b.push(3)
// [1, 2 ]
console.log(arr)

 

類型轉換

JavaScript的類型轉換本質是: 解釋器須要什麼類型, 則將根據須要將變量轉換爲其類型. 

字符串 數字 布爾值 對象

undefined

null

"undefined"

"null"

NaN

0

false

false

throws TypeError

throws TypeError

true

false

"true"

"false"

1

0

 

new Boolean(true)

new Boolean(false)

""

"1.2"

"one"

 

0

1.2

NaN

false

true

true

new String("")

new String("1.2")

new String("one")

0

-0

NaN

Infinity

-Infinity

1

"0"

"0"

"NaN"

"Infinity"

"-Infinity"

"1"

 

false

false

false

true

true

true

new Number(0)

new Number(-0)

new Number(NaN)

new Number(Infinity)

new Number(-Infinity)

new Number(1)

{}

[]

[9]

['a']

function(){}

後面解釋

""

"9"

使用join方法

後面解釋

後面解釋

0

9

NaN

NaN

true

true

true

true

true

 

 

轉換和相等性

進行"=="判斷時, JavaScript會進行類型轉換.

null == undefined ==> true

"0" == 0 ==> true

這裏類型轉換表明的意思是: a == b, 則a轉換爲b類型, 或者b轉換爲a類型, 再次進行比較. 因此對於null == undefined, 本質上是undefined轉換爲一個Object, 而後在和null進行比較.

而"0" == 0, 是將數字0轉換爲字符串"0", 而後再進行比較.

但能夠成功進行類型轉換, 不必定表示它們相等, 如undefined可轉換爲false, 但undefined == false的結果爲false.

在比較時候, 儘可能使用"==="而非"==".

 

顯示類型轉換

JavaScript在須要字符串狀況下, 會將變量轉換爲字符串; 其次, 在須要數字狀況下, 會將變量轉換爲數字.

Number類定義的toString()方法能夠接收表示轉換基數的可選參數. 若是不指定此參數, 轉換規則將是基於十進制:

let n = 17

n.toString() ==> "17"

n.toString(2) ==> "10001"

n.toString(8) ==> "21"

n.toString(16) ==> "11"

toFixed(): 根據小數點後的指定位數將數字轉換爲字符串, 它從不使用指數計數法.

toExponential(): 使用指數計數法將數字轉換爲指數形式的字符串, 其中小數點前只有一位, 小數點後的位數則由參數指定.

toPrecision(): 根據指定的有效數字位數將數字轉換成字符串. 若是有效數字的位數少於數字部分的位數, 則轉爲爲指數形式.

let n = 123456.789

n.toFixed(0) ==> "123457"

n.toFixed(2) ==> "123456.79"

n.toFixed(5) ==> "123456.78900"

n.toExponential(1) ==> "1.2e+5"

n.toExponential(3) ==> "1.235e+5"

n.toPrecision(4) ==> "1.235e+5"

n.toPrecision(7) ==> "123456.8"

n.toPrecision(10) ==> "123456.7890"

parseInt(): 儘量的將字符串轉換爲整數, 可接收第二個可選參數, 這個參數指定數字轉換的基數.

parseFloat(): 儘量的將字符串轉換爲浮點數.

 

對象轉換爲原始值

toString(): 返回一個反映這個對象的字符串.

valueOf(): 若是存在任意原始值, 它就默認將對象轉換爲表示它的原始值.

JavaScript中對象到字符串的轉換經歷如下步驟:

  1. 若是對象具備toString()方法, 則調用這個方法. 若是它返回一個原始值, JavaScript將這個值轉換爲字符串, 並返回這個字符串結果.
  2. 若是對象沒有toString()方法, 或者這個方法並不返回一個原始值, 那麼JavaScript會調用valueOf()方法, 若是存在這個方法, 則JavaScript調用它. 若是返回值是原始值, JavaScript將這個值轉換爲字符串, 並返回這個字符串結果.
  3. 否二, JavaScript拋出類型錯誤.

對象到數字的轉換經歷如下步驟:

  1. 若是對象具備valueOf()方法, 後者返回一個原始值, 則JavaScript將這個原始值轉換爲數字.
  2. 不然, 若是對象具備toString()方法, 後者返回一個原始值, 則JavaScript將其轉換並返回
  3. 不然, JavaScript拋出類型錯誤.

 

表達式和運算符

表達式

    因爲ES6中class的引入, 再也不使用函數當作一個對象來建立實例了. 而函數僅僅單純起到函數的做用, 而且將函數當作一個變量進行調用:

const func = () => console.log('hello world')
func()

若是存在相似class的需求, 例如用到繼承, 實例等, 可考慮引入class:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes

 

運算符

1. JavaScript運算符一般會根據操做數進行類型轉換, 因此"3" * "5"是合法的, 爲數字15.

若是想獲取一個數組的最大值, 最小值和平均值, 有個通用的寫法爲:

const arr = ['1', '3', 2, '44', 5, '222']
const max = arr.reduce((x, y) => x - y > 0 ? x : y)
const min = arr.reduce((x, y) => x - y > 0 ? y : x)
const avg = arr.reduce((x, y) => parseInt(x) + parseInt(y)) / arr.length
// 222 1 46.17
console.log(max, min, avg.toFixed(2))

備註: web開發中常常遇到字符串型數值.

這裏之因此使用x - y > 0是由於"-"會進行數值運算.

 

2. 一般使用"+"來將數組轉換爲字符串, 或者將字符串數值轉換爲數值:

let arr = [1, 2, 3]
// 1,2,3
console.log(arr + '')
// number
console.log(typeof +"3")

 

3. in用於判斷屬性是否存在與對象實例+原型中:

let point = {
    x: 1,
    y: 2,
}
// true
console.log('x' in point)
// true
console.log('toString' in point)
// false
console.log('xx' in point)

 

4. instanceof用於判斷左邊對象是否爲右邊類的實例.

const d = new Date()
// true
console.log(d instanceof Date)
// true
console.log(d instanceof Object)
// false
console.log(d instanceof RegExp)

 

5. typeof運算符用於判斷對象的類型:

x

typeof x

undefined

"undefined"

null

"object"

true或false

"boolean"

任意數字或NaN

"number"

任意字符串

"string"

任意函數

"function"

任意內置對象(非函數)

"object"

任意宿主對象 由編譯器自身決定

 

6. delete用於刪除一個對象的屬性, 對數組來講至關於賦值undefined:

let o = {x: 1, y:2}

delete o.x

o ==> Object {y: 2}

let arr = [11, 12, 13]

delete arr[1]

arr ==> [11, undefined × 1, 13]
相關文章
相關標籤/搜索