2023.06.16
const a = Array.of('one', 'two', 'three');
console.log(a); // ["one", "two", "three"]
class MyArray extends Array {
niftyMethod() {
// ...do something nifty...
}
}
const a = MyArray.of('one', 'two', 'three');
console.log(a instanceof MyArray); // true
console.log(a); // ["one", "two", "three"]
const a = Array.from('123');
console.log(a); // ["1", "2", "3"]
const b = Array.from({ length: 2, 0: 'one', 1: 'two' });
console.log(b); // ["one", "two"]
const c = Array.from('0123456789', Number);
console.log(c); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const a = Array.from({ length: 100 }, (_, index) => index);
// Or: const a = Array.from(Array(100), (_, index) => index);
console.log(a); // [0, 1, 2, 3, ... 99]
for (const index of ['one', 'two', 'three'].keys()) {
console.log(index);
}
// =>
// 0
// 1
// 2
const a = [, 'x', , , 'y'];
for (const index of a.keys()) {
console.log(index, index in a ? 'present' : 'absent');
}
// 배열 a는 인덱스 0, 2, 3에 엔트리가 없다.
// =>
// 0 "absent"
// 1 "present"
// 2 "absent"
// 3 "absent"
// 4 "present"
for (const index of ['one', 'two', 'three'].values()) {
console.log(index);
}
// =>
// "one"
// "two"
// "three"
const a = [, 'x', , , 'y'];
for (const value of a.values()) {
console.log(value);
}
// =>
// undefined
// "x"
// undefined
// undefined
// "y"
for (const entry of ["one", "two", "three"].entries()) {
console.log(entry);
}
// =>
// [0, "one"]
// [1, "two"]
// [2, "three"]
const a = [, undefined, , , "y"];
for (const [index, value] of a.entries()) {
console.log(index, value, index in a ? "present" : "absent");
}
// =>
// 0 undefined "absent"
// 1 undefined "present"
// 2 undefined "absent"
// 3 undefined "absent"
// 4 "y" "present"
const a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
console.log('before', a);
a.copyWithin(2, 8);
console.log('after ', a);
// =>
// before ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]
// after ["a", "b", "i", "j", "k", "f", "g", "h", "i", "j", "k"]
// 인덱스 2~4에 있는 앞쪽 엔트리를 복사본으로 덮어썼다.
const b = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
console.log('before', b);
b.copyWithin(4, 2);
console.log('after ', b);
// =>
// before ["a", "b", "c", "d", "e", "f", "g"]
// after ["a", "b", "c", "d", "c", "d", "e"]
// 배열을 확장하지 않고, 복사가 중지되었다. 코드에 종료 인덱스(세 번째 인수가) 없었으므로
const firstEven = [1, 2, 3, 4, 5, 6].find((value) => value % 2 == 0);
console.log(firstEven); // 2
const a = ['one', 'two', 'three'];
const x = a.find((value, index) => {
console.log(`Visiting index ${index}: ${value}`);
if (index === 0) {
a[2] = a[2].toUpperCase();
} else if (index === 1) {
a.push('four');
}
return value === 'four';
});
console.log(x);
// =>
// Visiting index 0: one
// Visiting index 1: two
// Visiting index 2: THREE
// undefined
const a = [1, 2, 3, 4, 5, 6];
const firstEven = a.findIndex((value) => value % 2 == 0);
console.log(firstEven); // 1 -- the first even value is the number 2 at index 1
console.log(Array(5).fill(42)); // [42, 42, 42, 42, 42]
const a = Array(2).fill({});
a[0].name = 'Joe';
a[1].name = 'Bob';
console.log(a[0].name); // "Bob"
const a = ['one', 'two', 'three'];
console.log(a.includes('two')); // true
console.log(a.includes('four')); // false
console.log(a.includes('one', 2)); // false, "one" is before index 2
const b = [NaN];
console.log(b.indexOf(NaN) !== -1); // false
console.log(b.includes(NaN)); // true
const original = [[1, 2, 3], 4, 5, [6, 7, 8]];
const flattened = original.flat();
console.log(flattened);
// => [1, 2, 3, 4, 5, 6, 7, 8]
const original = [
[1, 2, 3],
[
[4, 5, 6],
[7, 8, 9],
],
];
const flattened = original.flat();
console.log(flattened);
// => [1, 2, 3, [4, 5, 6], [7, 8, 9]];
const original = ['a', ['b', 'c', ['d', 'e', ['f', 'g', ['h', 'i']]]], 'j'];
const flattened = original.flat(Infinity);
console.log(flattened);
// => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
const flattened = [1, 2, 3, 4].flatMap((e) => e === 3 ? ["3a", "3b", "3c"] : e);
console.log(flattened);
// => [1, 2, "3a", "3b", "3c", 4]
const original = [1, 2, 3, 4];
const flattened = original.map((e) => (e === 3 ? ["3a", "3b", "3c"] : e)).flat();
console.log(flattened);
// => [1, 2, "3a", "3b", "3c", 4]
// (This example should probably use `toLocaleLowerCase` rather than `toLowerCase`, but
// it doesn't matter for the *specific* data used below. Still...)
const a = ["b", "B", "a", "A", "c", "C"];
a.sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase()));
console.log(a);
// 위 코드는 여러 가지의 가능한 결과를 생성할 수 있었다.
// ['a', 'A', 'b', 'B', 'c', 'C']
// ['A', 'a', 'b', 'B', 'c', 'C']
// ['A', 'a', 'B', 'b', 'c', 'C']
// ['A', 'a', 'B', 'b', 'C', 'c']
// ['a', 'A', 'b', 'B', 'c', 'C']
// ...
| 이름 | 값 타입 | 엔트리 사이즈 | 변환 작업 | 설명 |
| ----------------- | ---------- | --------------- | -------------------------------------------------------- | ---------------------------------- |
| Int8Array | Int8 | 1 | ToInt8 | 8비트 2의 보수 부호 있는 정수 |
| Uint8Array | Uint8 | 1 | ToUint8 | 8비트 부호 없는 정수 |
| Uint8ClampedArray | Uint8C | 1 | ToUint8Clamp | 8비트 부호 없는 정수 (클램프 변환) |
| Int16Array | Int16 | 2 | Tolnt16 | 16비트 2의 보수 부호 있는 정수 |
| Uint16Array | Uint16 | 2 | ToUint16 | 16비트 부호 없는 정수 |
| Int32Array | Int32 | 4 | ToInt32 | 32비트 2의 보수 부호 있는 정수 |
| Uint32Array | Uint32 | 4 | ToUint32 | 32비트 부호 없는 정수 |
| Float32Array | Float32 | 4 | IEEE-754-2008 사양 규칙을 사용하여 숫자가 Float32로 변환 | 32비트 IEEE-754 이진 부동 소수점 |
| Float64Array | Float64/ 8 | (필요하지 않음) | "숫자" | 64비트 IEEE-754 이진 부동 소수점 |
| BigInt64Array | Bigint64 | 8 | ToBigInt64 | ES2020의 새로운 기능 |
| BigUint64Array | BigUint64 | 8 | ToBigUint64 | ES2020의 새로운 기능 |
const a1 = new Int8Array(3);
a1[0] = 1;
a1[1] = "2"; // Note the string
a1[2] = 3;
console.log(a1); // Int8Array(3): [1, 2, 3] -- note 2 is a number
// Using `of`:
const a2 = Int8Array.of(1, 2, "3");
console.log(a2); // Int8Array(3): [1, 2, 3] -- "3" was converted to 3
// Using `from` with an array-like object:
const a3 = Int8Array.from({ length: 3, 0: 1, 1: "2" });
console.log(a3); // Int8Array(3): [1, 2, 0] -- undefined was converted to 0
// Using `from` with an array:
const a4 = Int8Array.from([1, 2, 3]);
console.log(a4); // Int8Array(3): [1, 2, 3]
const a = new Uint8Array(1);
a[0] = -25.4;
console.log(a[0]); // 231 !?!!
const a = new Int8Array(1);
a[0] = 25.4;
console.log(a[0]); // 25
a[0] = -25.4;
console.log(a[0]); // -25
const value = -25;
const max = 256;
const negative = value < 0;
const remainder = Math.abs(value) % max;
const result = negative ? max - remainder : remainder;
console.log(result); // 231
const a = new Int32Array(5);
console.log(a.buffer.byteLength); // 20 (bytes)
console.log(a.length); // 5 (entries, each taking four bytes)
const buf = new ArrayBuffer(20);
const b = new Int32Array(buf);
console.log(buf.byteLength); // 20 (bytes)
console.log(b.length); // 5 (entries, each taking four bytes)
const buf2 = new ArrayBuffer(18);
const c = new Int32Array(buf2); // RangeError: byte length of Int32Array
// should be a multiple of 4
const PNG_HEADER = Uint8Array.of(
0x89,
0x50,
0x4e,
0x47,
0x0d,
0x0a,
0x1a,
0x0a
);
function isPNG(byteData) {
return (
byteData.length >= PNG_HEADER.length &&
PNG_HEADER.every((b, i) => b === byteData[i])
);
}
function show(msg) {
const p = document.createElement("p");
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
document
.getElementById("file-input")
.addEventListener("change", function (event) {
const file = this.files[0];
if (!file) {
return;
}
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = () => {
const byteData = new Uint8Array(fr.result);
show(`${file.name} ${isPNG(byteData) ? "is" : "is not"} a PNG file.`);
};
fr.onerror = (error) => {
show(`File read failed: ${error}`);
};
});
const PNG_HEADER_1 = 0x89504e47; // Big-endian first Uint32 of PNG header
const PNG_HEADER_2 = 0x0d0a1a0a; // Big-endian second Uint32 of PNG header
const TYPE_IHDR = 0x49484452; // Big-endian type of IHDR chunk
function show(msg) {
const p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
document.getElementById('file-input').addEventListener('change', function (event) {
const file = this.files[0];
if (!file) {
return;
}
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = () => {
// INCORRECT, Uint32Array uses architecture endianness,
// this code will fail on a little-endian architecture
if (fr.result.byteLength >= 24) {
const data = new Uint32Array(fr.result, 0, 6);
if (data[0] === PNG_HEADER_1 && data[1] === PNG_HEADER_2 && data[3].getUint32(12) === TYPE_IHDR) {
const width = data[4];
const height = data[5];
show(`${file.name} is ${width} by ${height} pixels`);
return;
}
}
show(`${file.name} is not a PNG file.`);
};
fr.onerror = (error) => {
show(`File read failed: ${error}`);
};
});
new %TypedArray%(buffer[, start[, length]]): 주어진 버퍼를 사용하여 배열을 생성한다.
생성자의 매개변수는 아래와 같다.
ArrayBuffer는 다음 두 가지 방법으로 여러 유형의 배열 간에 공유할 수 있다.
겹침 없음: 버퍼의 고유한 부분만 사용하는 각 배열
const buf = new ArrayBuffer(20);
const bytes = new Uint8Array(buf, 0, 8);
const words = new Uint16Array(buf, 8);
console.log(buf.byteLength); // 20(바이트)
console.log(bytes.length); // 8(바이트)
console.log(words.length); // 6(6개의 2바이트(16비트) 워드 = 12바이트)
겹침 있음: 버퍼의 동일한 부분을 공유하는 배열
const buf = new ArrayBuffer(12);
const bytes = new Uint8Array(buf);
const words = new Uint16Array(buf);
console.log(words[0]); // 0
bytes[0] = 1;
bytes[1] = 1;
console.log(bytes[0]); // 1
console.log(bytes[1]); // 1
console.log(words[0]); // 257
// 1을 byte[0]과 byte[1]에 기록함으로써
// 단일 words[0] 엔트리를 구성하는 두 바이트 모두에 1을 기록했다.
// 하나는 상위 바이트, 하나는 하위 바이트
// 둘 다에 값 1을 넣으면 16비트 값 1 * 256 + 1, 즉 257(0x0101)을 얻는다. ( words[0]에서 얻은 값
class ByteArray extends Uint8Array {
static get [Symbol.species]() {
return Array;
}
}
const a = ByteArray.of(3, 2, 1);
console.log(a.map((v) => v * 2));
// => TypeError: Method %TypedArray%.prototype.map called on
// incompatible receiver [object Array]
%TypedArray%.prototype.set
// ==== Prep for the snippet:
const a1 = Uint8Array.of(1, 2, 3);
const a2 = Uint8Array.of(4, 5);
const a3 = Uint8Array.of(6, 7, 8, 9);
// ==== The snippet:
const all = new Uint8Array(a1.length + a2.length + a3.length);
all.set(a1);
all.set(a2, a1.length);
all.set(a3, a1.length + a2.length);
// ==== Not in the snippet, but so you can see it in action:
console.log(all);
%TypedArray%.prototype.subarray
const wholeArray = Uint8Array.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
const firstHalf = wholeArray.subarray(0, 5);
console.log(wholeArray); // Uint8Array [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(firstHalf); // Uint8Array [ 0, 1, 2, 3, 4 ]
firstHalf[0] = 100;
console.log(wholeArray); // Uint8Array [ 100, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(firstHalf); // Uint8Array [ 100, 1, 2, 3, 4 ]
const secondHalf = wholeArray.subarray(-5);
console.log(wholeArray); // Uint8Array [ 100, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(secondHalf); // Uint8Array [ 5, 6, 7, 8, 9 ]
secondHalf[1] = 60;
console.log(wholeArray); // Uint8Array [ 100, 1, 2, 3, 4, 5, 60, 7, 8, 9 ]
console.log(secondHalf); // Uint8Array [ 5, 60, 7, 8, 9 ]