稀疏數組 Sparse arraysjavascript
通常來講,JavaScript 中的數組都是稀疏數組-它們能夠擁有空槽,所謂空槽,指的就是數組的某個位置沒有任何值,既不是 undefined
,也不是 null
,由於數組只是索引到值的簡單映射。java
let a = new Array(3); console.log(a); // (3) [空 × 3] console.log(a[0]); // undefined a.forEach(function (x, i) { console.log(i, x) }); // 沒有打印任何東西 a.map(function (x, i) { return i }) // (3) [空 × 3]
密集數組 Dense arrays數組
let a = Array.apply(null, Array(3)); // 至關於 Array(undefined, undefined, undefined) console.log(a); // [ undefined, undefined, undefined ] console.log(a[0]); // undefined a.forEach(function (x, i) { console.log(i+". "+x) }); // 0 undefined // 1 undefined // 2 undefined a.map(function (x, i) { return i }) // [ 0, 1, 2 ]
按位移動操做符有兩個操做數:第一個是要被移動的數字,而第二個是要移動的長度。app
移動的方向根據操做符的不一樣而不一樣。prototype
按位移動會先將操做數轉換爲大端字節序順序(big-endian order)的32位整數,並返回與左操做數相同類型的結果。右操做數應小於 32位,不然只有最低 5 個字節會被使用。code
Big-Endian: 高位字節排放在內存的低地址端,低位字節排放在內存的高地址端,又稱爲"高位編址"。索引
Big-Endian是最直觀的字節序:ip
<<
左移內存
該操做符會將第一個操做數向左移動指定的位數。向左被移出的位被丟棄,右側用 0 補充。io
9 (base 10) -> 00000000000000000000000000001001 (base 2)
console.log(9 << 2); // 36 // 00000000000000000000000000001001 -> 00000000000000000000000000100100 = 36 (base 10)
>>
有符號右移
該操做符會將第一個操做數向右移動指定的位數。向右被移出的位被丟棄,拷貝最左側的位以填充左側。因爲新的最左側的位老是和之前相同,符號位沒有被改變。因此被稱做符號傳播。
console.log(9 >> 2); // 2 // 00000000000000000000000000001001 -> 00000000000000000000000000000010 = 2 (base 10)
console.log(-9 >> 2 ); // -3 由於符號被保留了 // 11111111111111111111111111110111 -> 11111111111111111111111111111101 = -3 (base 10)
>>>
無符號右移
該操做符會將第一個操做數向右移動指定的位數。向右被移出的位被丟棄,左側用0填充。由於符號位變成了 0,因此結果老是非負的。(譯註:即使右移 0 個比特,結果也是非負的。)
對於非負數,有符號右移和無符號右移老是返回相同的結果。例如 9 >>> 2 和 9 >> 2 同樣返回 2:
console.log(9 >>> 2); // 2 // 00000000000000000000000000001001 -> 00000000000000000000000000000010 = 2 (base 10)
可是對於負數卻不盡相同。 -9 >>> 2 產生 1073741821 這和 -9 >> 2 不一樣:
console.log(-9 >>> 2); // 1073741821 // 11111111111111111111111111110111 -> 00111111111111111111111111111101 = 1073741821 (base 10)
console.log([1, 2, 3, 4].slice(-1))
/** * 裁剪數組,從 start 位置開始到 end 結束,但不包括 end 自己的位置。 * 代替 Array.prototype.slice,確保密集數組被返回。 * * @param {Array} array 要裁剪的數組 * @param {number} [start=0] 開始的位置 | 負指數將被視爲距結束的偏移量。 * @param {number} [end=array.length] 結束的位置 | 負指數將被視爲距結束的偏移量。 * @returns {Array} 返回裁切後的數組 * @example * * var array = [1, 2, 3, 4] * _.slice(array, 2) * // => [3, 4] */ function slice(array, start, end) { // 若 array 爲 null 返回 [] let length = array == null ? 0 : array.length if (!length) { return [] } // 若 start 爲 null 取第 0 位 start = start == null ? 0 : start // 若 end 爲 undefined(沒傳該值),end 取數組 length end = end === undefined ? length : end // start 爲負值,若大於數組長度,start 取第零位,不然從最後覺得往前減 if (start < 0) { start = -start > length ? 0 : (length + start) } // 若結束位置大於數組 length 取 length end = end > length ? length : end if (end < 0) { end += length } // x >>> 0 保證 x 爲數字類型且爲正整數,在無心義的狀況下缺省值爲0。 length = start > end ? 0 : ((end - start) >>> 0) // start = start >>> 0 start >>>= 0 // 構建新數組並返回 let index = -1 const result = new Array(length) while (++index < length) { result[index] = array[index + start] } return result } export default slice