정리가 필요한 글(array.from_정적메소드)
Array.from의 내부 로직 구현 다음은 Array.from 메서드의 내부 로직을 간략히 구현한 코드입니다:
function customArrayFrom(arrayLike, mapFn, thisArg) {
// 1. 유사 배열 객체의 길이를 가져옵니다.
const length = arrayLike.length;
// 2. 새 배열을 생성합니다.
const result = new Array(length);
// 3. 각 요소를 초기화합니다.
for (let i = 0; i < length; i++) {
const value = arrayLike[i];
// 4. 맵핑 함수가 제공되었는지 확인하고, 제공되었다면 이를 적용합니다.
if (mapFn) {
result[i] = mapFn.call(thisArg, value, i, arrayLike);
} else {
result[i] = value;
}
}
// 5. 생성된 배열을 반환합니다.
return result;
}
// 사용 예시
const lengthObject = { length: 3 };
const newArray = customArrayFrom(lengthObject, () => Array(2).fill(0));
console.log(newArray);
// 출력: [[0, 0], [0, 0], [0, 0]]
코드 설명 유사 배열 객체의 길이 가져오기:
const length = arrayLike.length;
arrayLike.length를 통해 유사 배열 객체의 길이를 가져옵니다. 새 배열 생성:
const result = new Array(length);
길이가 length인 새로운 배열을 생성합니다. 각 요소 초기화:
for (let i = 0; i < length; i++) {
const value = arrayLike[i];
// 맵핑 함수가 제공되었는지 확인하고 적용
if (mapFn) {
result[i] = mapFn.call(thisArg, value, i, arrayLike);
} else {
result[i] = value;
}
}
반복문을 통해 각 요소를 초기화합니다. arrayLike[i]를 통해 유사 배열 객체의 각 요소를 가져옵니다. 맵핑 함수 mapFn이 제공되었다면, 이를 현재 요소에 적용합니다. thisArg가 제공되면 call 메서드를 사용하여 this 값을 설정합니다. 배열 반환:
return result;
초기화된 배열을 반환합니다. 실제 사용 예시
const lengthObject = { length: 3 };
const newArray = customArrayFrom(lengthObject, () => Array(2).fill(0));
console.log(newArray);
// 출력: [[0, 0], [0, 0], [0, 0]]
이 예시에서 customArrayFrom 함수는 { length: 3 }라는 유사 배열 객체를 기반으로 새로운 배열을 생성합니다. 각 요소는 콜백 함수 () => Array(2).fill(0)에 의해 [0, 0]으로 초기화됩니다.
결론 Array.from 메서드는 유사 배열 객체의 길이를 읽고, 새로운 배열을 생성한 후, 각 요소에 대해 맵핑 함수를 적용하여 초기화합니다. 위의 customArrayFrom 함수는 이러한 로직을 구현한 예시로, Array.from이 어떻게 동작하는지 이해하는 데 도움이 될 것입니다.
. 객체 리터럴과 유사 배열 객체에 대한 설명 객체 리터럴 객체 리터럴은 데이터를 키와 값의 쌍으로 저장하는 방법입니다. 이를 중학생에게 설명하자면, 객체 리터럴은 데이터를 저장할 수 있는 특별한 상자라고 생각할 수 있습니다. 이 상자 안에는 이름표가 붙은 여러 칸이 있고, 각 칸에는 데이터를 넣을 수 있습니다.
예를 들어:
const student = {
name: 'John',
age: 18
};
여기서 student는 객체입니다. 이 객체에는 name이라는 키가 있고, 그 값은 ‘John’입니다. 또 age라는 키가 있고, 그 값은 18입니다.
유사 배열 객체 유사 배열 객체는 배열처럼 동작하지만 실제 배열이 아닌 객체입니다. 이 객체는 length라는 속성을 가지고 있어서 마치 배열처럼 길이를 가질 수 있습니다.
예를 들어:
const arrayLike = {
length: 3
};
여기서 arrayLike는 유사 배열 객체입니다. length라는 속성만 가지고 있어서, 길이가 3인 배열처럼 보이지만 실제 배열은 아닙니다.
- 중괄호로 묶여있을 때와 묶여있지 않을 때의 차이
중괄호로 묶여있을 때
const lengthObject = { length: 3 }; const newArray = Array.from(lengthObject); console.log(newArray); // [undefined, undefined, undefined]여기서 { length: 3 }는 객체 리터럴입니다. Array.from은 이 객체를 유사 배열 객체로 해석하고, 길이가 3인 배열을 생성합니다. 각 요소는 undefined로 초기화됩니다.
중괄호로 묶여있지 않을 때
const lengthValue = 3;
const newArray = Array.from(lengthValue);
console.log(newArray); // Error: Array.from requires an array-like object - not a number
여기서 3은 단순한 숫자입니다. Array.from은 숫자를 유사 배열 객체로 해석할 수 없기 때문에 에러가 발생합니다.
- Array.from의 동작 원리와 2차원 배열 생성 Array.from이 반환하는 것은 키와 값을 가진 배열이 아니라, 입력받은 유사 배열 객체를 기반으로 실제 배열을 생성하는 것입니다. 이를 쉽게 설명하기 위해 도식화와 함께 설명드리겠습니다.
단계별 설명 유사 배열 객체 생성:
const lengthObject = { length: 3 };
Array.from을 사용한 배열 생성:
const newArray = Array.from(lengthObject, () => Array(2).fill(0));
여기서 콜백 함수 () => Array(2).fill(0)는 각 요소를 길이가 2이고, 0으로 채워진 배열로 초기화합니다.
동작 과정 lengthObject는 길이가 3인 유사 배열 객체입니다. Array.from은 이 객체를 기반으로 배열을 생성합니다. 콜백 함수는 각 인덱스마다 호출되어 새로운 배열을 반환합니다. 도식화
입력: { length: 3 }, () => Array(2).fill(0)
과정:
1. 유사 배열 객체 { length: 3 }를 배열로 변환
2. 각 인덱스에 대해 콜백 함수 호출
- 첫 번째 인덱스: () => [0, 0] => [0, 0]
- 두 번째 인덱스: () => [0, 0] => [0, 0]
- 세 번째 인덱스: () => [0, 0] => [0, 0]
결과: [[0, 0], [0, 0], [0, 0]]
코드 실행 결과
const newArray = Array.from({ length: 3 }, () => Array(2).fill(0));
console.log(newArray);
// 출력: [[0, 0], [0, 0], [0, 0]]
여기서 newArray는 3개의 요소를 가진 배열이며, 각 요소는 [0, 0] 배열로 초기화되었습니다. 이는 Array.from이 유사 배열 객체의 length 값을 읽어 배열을 생성하고, 각 인덱스마다 콜백 함수를 호출하여 새 배열을 생성하기 때문입니다.
결론 객체 리터럴: 데이터를 키와 값의 쌍으로 저장하는 방법. 유사 배열 객체: 배열처럼 동작하지만 실제 배열은 아닌 객체로, length 속성을 가집니다. 중괄호 사용: 객체 리터럴을 생성하기 위해 중괄호 {}를 사용하며, 이는 Array.from이 유사 배열 객체로 인식하게 합니다. Array.from 동작 원리: 유사 배열 객체의 길이를 기반으로 배열을 생성하고, 콜백 함수를 사용하여 각 요소를 초기화합니다. 이해를 돕기 위해 도식화와 함께 설명해 보았습니다. Array.from의 동작 원리와 유사 배열 객체에 대한 이해가 도움이 되길 바랍니다.
{ length: N + 1 }는 객체 리터럴로, Array.from 메서드가 유사 배열 객체를 생성하기 위해 사용됩니다. 왜 이 인자가 중괄호로 묶여있는지, 그리고 유사 배열 객체가 무엇인지 더 깊이 이해하기 위해 설명드리겠습니다.
객체 리터럴과 유사 배열 객체 { length: N + 1 }는 객체 리터럴(object literal)입니다. 객체 리터럴은 중괄호 {}를 사용하여 키-값 쌍의 모음을 정의합니다. 여기서 length라는 키와 N + 1이라는 값이 있습니다.
유사 배열 객체(array-like object)는 배열처럼 행동하지만 실제 배열은 아닌 객체를 말합니다. 유사 배열 객체는 length 속성을 가지고 있고, 배열 메서드처럼 인덱스를 통해 요소에 접근할 수 있습니다.
왜 중괄호로 묶여있는가? Array.from 메서드는 배열이나 유사 배열 객체를 새로운 배열로 변환합니다. Array.from이 요구하는 것은 반복 가능한 객체(iterable object) 또는 유사 배열 객체입니다. { length: N + 1 }는 유사 배열 객체를 나타내기 위해 사용됩니다.
이 객체는 length 속성을 통해 배열의 길이를 지정할 수 있습니다. 즉, Array.from은 { length: N + 1 }를 보고 길이가 N + 1인 배열을 생성할 준비를 합니다. 이 때 실제 요소는 정의되지 않으며, 각 요소는 undefined로 초기화됩니다.
예시 간단한 예시를 통해 설명하겠습니다:
const lengthObject = { length: 3 };
const newArray = Array.from(lengthObject);
console.log(newArray); // [undefined, undefined, undefined]
이 예시에서 { length: 3 }는 길이가 3인 유사 배열 객체를 나타냅니다. Array.from은 이 객체를 배열로 변환하여 [undefined, undefined, undefined]를 생성합니다.
매개변수와의 연관 Array.from 메서드는 두 번째 인자로 맵핑 함수를 받을 수 있습니다. 이 함수는 생성된 배열의 각 요소에 대해 호출되며, 새로운 배열의 요소로 대체됩니다.
Array.from 사용 예시 이제 원래 코드로 돌아가서, 왜 { length: N + 1 }와 () => Array(M + 1).fill(0)을 사용하는지 설명해보겠습니다.
const prefixSum = Array.from({ length: N + 1 }, () => Array(M + 1).fill(0));
동작 과정 유사 배열 객체 생성:
{ length: N + 1 }는 길이가 N + 1인 유사 배열 객체를 나타냅니다. 이 객체는 실제로 요소를 가지고 있지는 않지만, Array.from이 새로운 배열을 생성할 때 참조할 길이 정보를 제공합니다. 콜백 함수 적용:
Array.from은 길이가 N + 1인 배열을 생성할 때, 각 인덱스에 대해 콜백 함수 () => Array(M + 1).fill(0)를 호출합니다. 이 콜백 함수는 길이가 M + 1인 배열을 생성하고 모든 요소를 0으로 채웁니다. 최종 배열 생성:
Array.from은 콜백 함수의 반환 값을 사용하여 최종 배열을 생성합니다. 결과적으로 prefixSum은 (N + 1) x (M + 1) 크기의 2차원 배열이 됩니다. 각 내부 배열은 [0, 0, …, 0] (길이 M + 1)로 초기화됩니다. 전체 코드 예시
const N = 2;
const M = 3;
const prefixSum = Array.from({ length: N + 1 }, () => Array(M + 1).fill(0));
console.log(prefixSum);
이 코드는 다음과 같은 출력을 생성합니다:
[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
여기서 prefixSum은 3x4 크기의 2차원 배열입니다. 각 내부 배열의 길이는 4(M + 1)이고, 모든 요소는 0으로 초기화되어 있습니다.
결론 { length: N + 1 }는 길이가 N + 1인 유사 배열 객체를 생성하기 위해 사용됩니다. 이는 Array.from 메서드에 의해 실제 배열로 변환됩니다. 콜백 함수 () => Array(M + 1).fill(0)는 각 요소를 길이가 M + 1인 배열로 초기화하는 역할을 합니다. 이 과정은 prefixSum과 같은 2차원 배열을 효율적으로 초기화하는 데 매우 유용합니다.
생성자의 정적 메서드 (Static Methods) 정적 메서드는 특정 클래스 또는 생성자 함수에 속한 메서드로, 인스턴스가 아닌 클래스 자체에서 호출됩니다. 정적 메서드는 클래스의 인스턴스를 생성하지 않고도 호출할 수 있습니다.
특징 클래스 또는 생성자 함수 자체에 바인딩됩니다. 인스턴스가 아닌 클래스 또는 생성자 함수 이름으로 호출됩니다. 인스턴스의 속성이나 메서드에 접근할 수 없습니다. 예시
class MathUtil {
// 정적 메서드
static add(a, b) {
return a + b;
}
}
// 정적 메서드 호출
console.log(MathUtil.add(2, 3)); // 5
프로토타입 메서드 (Prototype Methods) 프로토타입 메서드는 특정 객체의 인스턴스에 바인딩되는 메서드입니다. 이 메서드는 생성자의 인스턴스를 통해 호출됩니다.
특징 생성자의 인스턴스에 바인딩됩니다. 인스턴스를 통해 호출됩니다. 인스턴스의 속성과 메서드에 접근할 수 있습니다. 예시
class Person {
constructor(name) {
this.name = name;
}
// 프로토타입 메서드
greet() {
return `Hello, my name is ${this.name}`;
}
}
// 인스턴스 생성
const person = new Person('Alice');
// 프로토타입 메서드 호출
console.log(person.greet()); // "Hello, my name is Alice"
정적 메서드와 프로토타입 메서드의 차이 호출 방식 정적 메서드: 클래스 또는 생성자 함수 자체에서 호출됩니다.
ClassName.staticMethod();
프로토타입 메서드: 클래스 또는 생성자 함수의 인스턴스를 통해 호출됩니다.
instanceName.prototypeMethod();
접근 권한 정적 메서드: 클래스 또는 생성자 함수의 인스턴스 속성이나 다른 프로토타입 메서드에 접근할 수 없습니다. 프로토타입 메서드: 클래스 또는 생성자 함수의 인스턴스 속성과 다른 프로토타입 메서드에 접근할 수 있습니다. 예시: Array.from과 프로토타입 메서드 Array.from은 Array 생성자의 정적 메서드로, 배열 인스턴스가 아닌 Array 생성자 자체에서 호출됩니다.
정적 메서드 예시 (Array.from)
// 유사 배열 객체를 배열로 변환
const arrayLike = { length: 2, 0: 'a', 1: 'b' };
const array = Array.from(arrayLike);
console.log(array); // ['a', 'b']
프로토타입 메서드 예시 (Array.prototype.map)
// 배열의 각 요소에 함수를 적용하여 새 배열을 생성
const arr = [1, 2, 3];
const doubled = arr.map(x => x * 2);
console.log(doubled); // [2, 4, 6]
정리 정적 메서드: 클래스나 생성자 함수 자체에 속하며, 인스턴스가 아닌 클래스 또는 생성자 이름을 통해 호출됩니다. 인스턴스의 속성이나 다른 메서드에 접근하지 않습니다. 예: Array.from, Math.max, Object.keys 프로토타입 메서드: 클래스나 생성자 함수의 인스턴스에 속하며, 인스턴스를 통해 호출됩니다. 인스턴스의 속성과 다른 메서드에 접근할 수 있습니다. 예: Array.prototype.map, String.prototype.toUpperCase, Date.prototype.getTime 이 차이를 이해하면 JavaScript에서 클래스와 객체의 동작 방식을 더 잘 이해할 수 있습니다.
좀 더 알기 쉽게 중학생에게 설명하듯 설명주세요
물론입니다! 중학생이 이해할 수 있도록, 정적 메서드와 프로토타입 메서드의 차이를 간단한 비유와 함께 설명하겠습니다.
정적 메서드 (Static Methods) 비유 정적 메서드는 특정 클래스 자체에 속하는 기능입니다. 예를 들어, 학교에 School이라는 클래스가 있다고 합시다. 이 클래스에는 학교 전체에 관한 정보를 얻는 기능이 있습니다. 이 기능은 학교에 다니는 학생들이 사용하는 것이 아니라, 학교 자체에서 사용하는 기능입니다.
예시
class School {
static getSchoolName() {
return "Greenwood High School";
}
}
// 정적 메서드 호출
console.log(School.getSchoolName()); // "Greenwood High School"
여기서 getSchoolName은 School 클래스에 속하는 정적 메서드입니다. 학생 인스턴스가 아닌 School 클래스 자체에서 호출됩니다.
프로토타입 메서드 (Prototype Methods) 비유 프로토타입 메서드는 특정 클래스의 인스턴스에 속하는 기능입니다. 예를 들어, 학교에 다니는 Student라는 클래스가 있다고 합시다. 이 클래스에는 학생 개개인이 사용할 수 있는 기능들이 있습니다. 예를 들어, 학생은 자신의 이름을 말할 수 있는 기능을 가질 수 있습니다.
예시
class Student {
constructor(name) {
this.name = name;
}
// 프로토타입 메서드
sayName() {
return `My name is ${this.name}`;
}
}
// 인스턴스 생성
const student1 = new Student('Alice');
const student2 = new Student('Bob');
// 프로토타입 메서드 호출
console.log(student1.sayName()); // "My name is Alice"
console.log(student2.sayName()); // "My name is Bob"
여기서 sayName은 Student 클래스에 속하는 프로토타입 메서드입니다. 각 학생 인스턴스(student1, student2)가 자신만의 이름을 말할 수 있습니다.
차이점 요약 정적 메서드:
클래스 자체에 속합니다. 인스턴스가 아니라 클래스 이름을 통해 호출됩니다. 예: 학교의 이름을 얻는 기능 (School.getSchoolName()). 프로토타입 메서드:
클래스의 인스턴스에 속합니다. 인스턴스를 통해 호출됩니다. 예: 학생의 이름을 말하는 기능 (student1.sayName()). 다시 설명하는 예시: Array와 Array.from Array.from은 정적 메서드입니다. 즉, 배열 인스턴스가 아니라 Array 클래스 자체에서 호출됩니다.
정적 메서드 예시 (Array.from)
// 유사 배열 객체를 배열로 변환
const arrayLike = { length: 2, 0: 'a', 1: 'b' };
const array = Array.from(arrayLike);
console.log(array); // ['a', 'b']
Array.from은 Array 클래스에 속하는 정적 메서드입니다. 배열 인스턴스 없이 Array 자체에서 호출됩니다.
프로토타입 메서드 예시 (Array.prototype.map)
// 배열의 각 요소에 함수를 적용하여 새 배열을 생성
const arr = [1, 2, 3];
const doubled = arr.map(x => x * 2);
console.log(doubled); // [2, 4, 6]
map은 배열 인스턴스에 속하는 프로토타입 메서드입니다. 배열 인스턴스(arr)를 통해 호출됩니다.
정리 정적 메서드는 클래스 자체에서 호출됩니다. 예를 들어, Array.from은 Array 클래스에서 호출됩니다. 프로토타입 메서드는 클래스의 인스턴스에서 호출됩니다. 예를 들어, map 메서드는 배열 인스턴스에서 호출됩니다.
댓글남기기