天天看點

js備忘錄

1. splice,slice,split三者差別

splice

splice() 方法通過删除或替換現有元素或者原地添加新的元素來修改數組,并以數組形式傳回被修改的内容。(

此方法會改變原數組,擷取的是新的數組

)

文法:

參數:

index —— 必需。整數,規定添加/删除項目的位置,使用負數可從數組結尾處規定位置。

howmany ——必需。要删除的項目數量。如果設定為 0,則不會删除項目。

item1, …, itemX —— 可選。向數組添加的新項目。

總結:

  • 如果splice() 方法中存在一個或兩個參數,表示删除操作。如果存在三個參數或三個以上參數的時候要着重記住第二個元素,若第二個元素為0就是添加操作,添加第三個及後面的元素,如果第二個元素不為0則是替換操作,替換第三個及後面的元素。
  • splice() 方法可删除從 index 處開始的零個或多個元素,并且用參數清單中聲明的一個或多個值來替換那些被删除的元素。
  • 如果從 arrayObject 中删除了元素,則傳回的是含有被删除的元素的數組。
slice

用于截取數組,并傳回截取到的新的數組,數組與字元串對象都使用(

此方法對原數組不會改變

文法:

參數:

start::必需,規定從何處開始選取。如是負數,規定從數組尾部開始算起,也就是說,-1指的是最後一個元素,以此類推;

end:可選,規定從何處結束選取。該參數是數組片段結束處的數組下标。如果沒有指定該參數,那麼切分的數組包含從star到數組結束的所有元素。如果這個參數是負數,那麼它規定的是從數組尾部開始算起的元素。

傳回值:一個新的數組,包含從start 到end(

不包括該元素

)的ArrayObject 中的元素。

split

split() 方法用于把一個字元串分割成字元串數組。 (

此方法不改變原始字元串。

)

注: 如果把空字元串 (“”) 用作 separator,那麼 stringObject 中的每個字元之間都會被分割。

文法:

string.split(separator,limit)
           

參數:

separator :

可選

。字元串或正規表達式,從該參數指定的地方分割 string Object。

limit :可選。該參數可指定傳回的數組的最大長度。如果設定了該參數,傳回的子串不會多于這個參數指定的數組。如果沒有設定該參數,整個字元串都會被分割,不考慮它的長度。

2. isNaN與Number.isNaN的差別

函數 isNaN 接收參數後,會先嘗試将這個參數轉換為數值,任何不能被轉換為數值的的值都會傳回 true,是以非數字值傳入也會傳回 true ,會影響 NaN 的判斷。

函數 Number.isNaN 會首先判斷傳入參數是否為數字,如果是數字再繼續判斷是否為 NaN ,不會進行資料類型的轉換,這種方法對于 NaN 的判斷更為準确。

3. 其他值到字元串的轉換規則

  • Null 和 undefined 類型 ,null 轉換為 “null”,undefined 轉換為 “undefined”。
  • Boolean 類型,true 轉換為 “true”,false 轉換為 “false”。
  • Number 類型的值直接轉換,不過那些極小和極大的數字會使用指數形式。
  • Symbol 類型的值直接轉換,但是隻允許顯式強制類型轉換,使用隐式強制類型轉換會産生錯誤。
  • 對普通對象來說,除非自行定義 toString() 方法,否則會調用 toString()(Object.prototype.toString())來傳回内部屬性 [[Class]] 的值,如"[object Object]"。如果對象有自己的 toString() 方法,字元串化時就會調用該方法并使用其傳回值。

4. 其他值到數字值的轉換規則

  • undefined 類型的值轉換為 NaN。
  • Null 類型的值轉換為 0。
  • Boolean 類型的值,true 轉換為 1,false 轉換為 0。
  • String 類型的值轉換如同使用 Number() 函數進行轉換,如果包含非數字值則轉換為 NaN,空字元串為 0。
  • Symbol 類型的值不能轉換為數字,會報錯。
  • 對象(包括數組)會首先被轉換為相應的基本類型值,如果傳回的是非數字的基本類型值,則再遵循以上規則将其強制轉換為數字。

為了将值轉換為相應的基本類型值,抽象操作 ToPrimitive 會首先(通過内部操作 DefaultValue)檢查該值是否有valueOf()方法。如果有并且傳回基本類型值,就使用該值進行強制類型轉換。如果沒有就使用 toString() 的傳回值(如果存在)來進行強制類型轉換。

如果 valueOf() 和 toString() 均不傳回基本類型值,會産生 TypeError 錯誤。

5. 其他值到布爾類型的值的轉換規則

以下這些是假值:

  • undefined
  • null
  • false
  • +0、-0 和 NaN
  • “”

假值的布爾強制類型轉換結果為 false。從邏輯上說,假值清單以外的都應該是真值。

6. ||與&&操作符的傳回值

  • ||傳回第一個為true的操作數值
  • &&傳回第一個為false的操作數值

例如:

console.log(0||1||2)		//列印1
console.log(1&&0&&false)		//列印0
           

|| 和 && 傳回它們其中一個操作數的值,而非條件判斷的結果

7. Object.is() 與比較操作符 “=”、“” 的差別

  • 使用雙等号(==)進行相等判斷時,如果兩邊的類型不一緻,則會進行強制類型轉換後再進行比較。
  • 使用三等号(===)進行相等判斷時,如果兩邊的類型不一緻時,不會做強制類型轉換,直接傳回 false。
  • 使用 Object.is 來進行相等判斷時,一般情況下和三等号的判斷相同,它處理了一些特殊的情況,比如 -0 和 +0 不再相等,兩個 NaN 是相等的。

8. JavaScript 中的隐式類型轉換

首先要介紹

ToPrimitive

方法,這是 JavaScript 中每個值隐含的自帶的方法,用來将值 (無論是基本類型值還是對象)轉換為基本類型值。如果值為基本類型,則直接傳回值本身;如果值為對象,其看起來大概是這樣:

/**
* @obj 需要轉換的對象
* @type 期望的結果類型
*/
ToPrimitive(obj,type)
           

type

的值為

number

或者

string

(1)當

type

number

時規則如下:

  • 調用

    obj

    valueOf

    方法,如果為原始值,則傳回,否則下一步;
  • 調用

    obj

    toString

    方法,後續同上;
  • 抛出

    TypeError

    異常。

(2)當

type

string

時規則如下:

  • 調用

    obj

    toString

    方法,如果為原始值,則傳回,否則下一步;
  • 調用

    obj

    valueOf

    方法,後續同上;
  • 抛出

    TypeError

    異常。

可以看出兩者的主要差別在于調用

toString

valueOf

的先後順序。預設情況下:

  • 如果對象為

    Date

    對象,則

    type

    預設為

    string

  • 其他情況下,

    type

    預設為

    numbe

    r。

總結上面的規則,對于

Date

以外的對象,轉換為基本類型的大概規則可以概括為一個函數:

var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN
           

而 JavaScript 中的隐式類型轉換主要發生在

+、-、*、/

以及

==、>、<

這些運算符之間。而這些運算符隻能操作基本類型值,是以在進行這些運算前的第一步就是将兩邊的值用

ToPrimitive

轉換成基本類型,再進行操作。

以下是基本類型的值在不同操作符的情況下隐式轉換的規則 (對于對象,其會被

ToPrimitive

轉換成基本類型,是以最終還是要應用基本類型轉換規則)

  1. +

    操作符:

    +

    操作符的兩邊有至少一個string類型變量時,兩邊的變量都會被隐式轉換為字元串;其他情況下兩邊的變量都會被轉換為數字。
1 + '23' // '123'
1 + false // 1 
1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number
'1' + false // '1false'
false + true // 1
           
  1. -、*、\

    操作符:

    NaN

    也是一個數字
1 * '23' // 23
1 * false // 0
1 / 'aa' // NaN
           
  1. ==

    操作符:
3 == true // false, 3 轉為number為3,true轉為number為1
'0' == false //true, '0'轉為number為0,false轉為number為0
'0' == 0 //true '0'轉為number為0
           
  1. 對于

    <

    >

    比較符:

如果兩邊都是字元串,則比較字母表順序:

'ca' < 'bd' // false
'a' < 'b' // true
           

其他情況下,轉換為數字再比較:

'12' < 13 // true
false > -1 // true
           

以上說的是基本類型的隐式轉換,而對象會被ToPrimitive轉換為基本類型再進行轉換:

let a = {}
a > 2 // false
           

其對比過程如下:

a.valueOf() // {}, 上面提到過,ToPrimitive預設type為number,是以先valueOf,結果還是個對象,下一步
a.toString() // "[object Object]",現在是一個字元串了
Number(a.toString()) // NaN,根據上面 < 和 > 操作符的規則,要轉換成數字
NaN > 2 //false,得出比較結果
           

NaN

與任何值作比較都傳回

false

(除Object.is(NaN,NaN)傳回

true

外)

又比如:

let a = {name:'Jack'}
let b = {age: 18}
a + b // "[object Object][object Object]"
           

運算過程如下:

a.valueOf() // {},上面提到過,ToPrimitive預設type為number,是以先valueOf,結果還是個對象,下一步
a.toString() // "[object Object]"
b.valueOf() // 同理
b.toString() // "[object Object]"
a + b // "[object Object][object Object]"
           

9.

+

操作符什麼時候用于字元串的拼接

根據 ES5 規範,如果某個操作數是字元串或者能夠通過以下步驟轉換為字元串的話,+ 将進行拼接操作。如果其中一個操作數是對象(包括數組),則首先對其調用

ToPrimitive

抽象操作,該抽象操作再調用 [[DefaultValue]],以數字作為上下文。如果不能轉換為字元串,則會将其轉換為數字類型來進行計算。

簡單來說就是,如果 + 的其中一個操作數是字元串(或者通過以上步驟最終得到字元串),則執行字元串拼接,否則執行數字加法。

那麼對于除了加法的運算符來說,隻要其中一方是數字,那麼另一方就會被轉為數字。

例如:

console.log([1,2]+1)		//"1,21"
//運算過程
[1,2].valueOf() // [1,2],上面提到過,ToPrimitive(除Date對象)預設type為number,是以先valueOf,結果還是個對象,下一步
[1,2].valueOf().toString()	//"1,2",此時[1,2]轉換為字元串,則進行字元串拼接
console.log("1,2"+1)		//"1,21"
           

繼續閱讀