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
r。numbe
總結上面的規則,對于
Date
以外的對象,轉換為基本類型的大概規則可以概括為一個函數:
var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN
而 JavaScript 中的隐式類型轉換主要發生在
+、-、*、/
以及
==、>、<
這些運算符之間。而這些運算符隻能操作基本類型值,是以在進行這些運算前的第一步就是将兩邊的值用
ToPrimitive
轉換成基本類型,再進行操作。
以下是基本類型的值在不同操作符的情況下隐式轉換的規則 (對于對象,其會被
ToPrimitive
轉換成基本類型,是以最終還是要應用基本類型轉換規則)
-
操作符:+
操作符的兩邊有至少一個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
-
操作符:-、*、\
也是一個數字NaN
1 * '23' // 23
1 * false // 0
1 / 'aa' // NaN
-
操作符:==
3 == true // false, 3 轉為number為3,true轉為number為1
'0' == false //true, '0'轉為number為0,false轉為number為0
'0' == 0 //true '0'轉為number為0
- 對于
和<
比較符:>
如果兩邊都是字元串,則比較字母表順序:
'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
(除Object.is(NaN,NaN)傳回
false
外)
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"