const arr = [1,2,3];
console.log(arr); // 콘솔을 찍었을때 Symbol(Symbol.iterlator)의 속성을 확인 할 수 있다
const arr2 = new Array(3).fill(0);
console.log(arr2);
여기서 new
키워드는 무엇일까 여기에는 class 가 숨어있다 Array라는 class에서 상속을 받기 때문에 prototype으로 손쉽게 사용할 수 있다.
배열은 순서가 있다
객체는 순서가 없다
객체에서 상속을 받아서 내려온 것이 배열이다
return
이 있는지 없는지의 차이를 아는지 물어보는것이다.형변환
을 위한 메소드인지 아는가map : 배열의 각 요소에 대해 주어진 함수를 실행하고, 그 결과를 포함하는 새로운 배열을 반환합니다. 예를 들어, 배열의 모든 요소를 제곱하거나 특정 속성만 추출하여 새로운 배열을 만드는 데 사용할 수 있습니다.
filter : 배열의 각 요소에 대해 주어진 테스트 함수를 실행하고, 그 함수를 통과하는 요소만으로 이루어진 새 배열을 반환합니다. 예를 들어, 배열에서 특정 조건을 만족하는 요소만 선택하려는 경우 사용합니다.
reduce : 배열의 각 요소에 대해 주어진 reducer 함수를 실행하고, 하나의 출력값을 반환합니다. 이는 종종 배열의 요소를 결합하거나 압축하는 데 사용됩니다. 예를 들어, 배열의 모든 요소의 합계를 계산하거나 배열의 요소를 이용해 객체를 생성하는 경우 사용합니다.
reduce의 기본형 : .reduce((acc, current) => , {});
const url = 'https://www.youtube.com/watch?v=exCdaVKG&t=5s';
const [baseUrl, qs] = url.split('?');
// ['https://www.youtube.com/watch', 'v=exCdaVKG&t=5s']
// {v: 'exC...', t: '5s'} 의 값을 얻으려면?
const queryObj = qs.split('&')
.map((query) => query.split("="))
// 배열형태이다 [['v','exCdaVKG'],['t','5s']]
// 배열에서 객체로 형변환이 필요함 >> reduce 사용
.reduce((acc,[key,value]) => ({...acc,[key]:value}),
{});
console.log(queryObj); // {v: 'exC...', t: '5s'}
//다시 문자열 전환 (역산하는방법)
baseUrl+'?'+
Object.entries(queryObj)
.map(([key,value]) => `${key}=${value}`)
.join("&");
forEach : 배열의 각 요소에 대해 주어진 함수를 실행합니다. 반환값이 없습니다(즉, 새로운 배열을 생성하지 않습니다). 주로 배열의 각 요소에 대해 어떤 작업을 수행하려는 경우 사용합니다.
const myArr = [1,2,3,4,5];
const doubledArr = myArr.forEach((v)=> return(v*2));
console.log(doubledArr); // undefined
console.log(myArr); // [1,2,3,4,5]
forEach 메소드는 리턴값이 없는 메소드이기 때문에 함수에 return을 명시하더라도 리턴값이 없다.
그리고 원본배열도 변경되지 않는다.
DOM을 변경하는 것이 아니라 딱 순회만 할 때(액션만취하고빠질때) 사용이된다.
ex)무한스크롤 구현등
일단 이런 문제가 나오면 실제 메소드를 한번 돌려서 과정들을 생각해본다
const arr = [1, 2, 3, 4, 5];
arr.map((v) => v * 2);
//프로토 타입에 직접 주입
// this 사용시에는 arrow function 사용x
Array.prototype.myMap = function(callback) {
let result = [];
console.log(this); // [1, 2, 3, 4, 5]
for (let i = 0; i< this.length; i++) {
result.push(callback(this[i]));
}
return result;
}
arr.myMap((v) => v * 2); //[2, 4, 6, 8, 10]
Array.prototype.myFilter = function(callback){
let result = [];
for(let i = 0; i < this.length; i++) {
if(callback(this[i], i, this)) {
result.push(this[i]);
}
}
return result;
};
Array.prototype.myReduce = function(callback, initialValue) {
let accumulator = initialValue === undefined ? this[0] : initialValue;
for(let i = initialValue === undefined ? 1 : 0; i < this.length; i++) {
accumulator = callback(accumulator, this[i], i, this);
}
return accumulator;
};
slice : 배열의 부분적인 복사본을 생성합니다. 원본 배열은 변경되지 않습니다. 시작 인덱스와 종료 인덱스를 인자로 받아, 시작 인덱스부터 종료 인덱스 전까지의 요소를 새로운 배열로 반환합니다.
splice : 배열의 특정부분을 제거하거나 추가하며, 원본 배열을 변경합니다. 시작 인덱스와 제거할 요소의 갯수, 그리고 추가할 요소를 인자로 받아 제거된 요소를 배열로 반환하며, 원본 배열은 제거된 요소를 제외하거나 추가한 요소를 포함하는 상태로 변경됩니다.
배열 내장함수
import React, { useState } from "react";
const INIT_STATE = {
id: "",
password: "",
userName: ""
};
const RULE = {
id: (value) => value.includes("@"),
password: (value) => value.length >= 8,
userName: (value) => value.length >= 2
};
export default function App() {
const [formData, setFormData] = useState(INIT_STATE);
const onChangeInput = ({ target }: any) => {
const { name, value } = target;
setFormData({ ...formData, [name]: value });
};
const isAllValid = Object.entries(formData).every(([k, v]) => RULE[k](v));
return (
<form>
<input type="text" name="userName" onChange={onChangeInput} />
<input type="text" name="id" onChange={onChangeInput} />
<input type="password" name="password" onChange={onChangeInput} />
{isAllValid && <button>제출</button>}
</form>
);
}
import React, { useState } from "react";
import "./styles.css";
import Input from "./Input";
const INIT_STATE = {
id: "",
password: "",
userName: ""
};
const RULE = {
id: (value) => value.includes("@"),
password: (value) => value.length >= 8,
userName: (value) => value.length >= 2
};
export default function App() {
const [formData, setFormData] = useState(INIT_STATE);
const onChangeInput = ({ target }: any) => {
const { name, value } = target;
setFormData({ ...formData, [name]: value });
};
const isAllValid = Object.entries(formData).every(([k, v]) => RULE[k](v));
return (
<form>
<Input type="text" name="userName" onChange={onChangeInput} />
<Input type="text" name="id" onChange={onChangeInput} />
<Input type="password" name="password" onChange={onChangeInput} />
{Input({name: 'secondName', onChange: onChangeInput})} /
{isAllValid && <button>제출</button>}
</form>
);
}
import React from "react";
// 뭔가 중요한 prop이 있다면 따로 분리해서 사용할 수 있다. (Rest Parameter)
// 이때 ...props에는 name을 제외한 props 들이 들어있다
const Input = ({ name, ...props }) => {
return (
<div>
<p>{name}</p>
<input className="styled-input" {...props} />
</div>
);
};
export default Input;
Array.prototype.slice
: 원본 배열을 변경하지 않고 새 배열을 반환Array.prototype.concat
: 원본 배열을 변경하지 않고 새 배열을 반환(...배열변수명)
: 이 연산자를 사용하면 쉽게 배열 복제 가능Array.from
: 이 메서드는 iterable 객체나 array-like 객체를 새 배열로 변환모두 새 배열을 반환하므로 원본 배열은 변경되지 않는다. 그러나 이 방법은 모두
얕은 복사
를 수행한다.
즉, 배열 요소가 객체인 경우, 새 배열은 원본 배열의 객체에 대한 참조를 가지게 되므로 이러한 객체를 변경하면 원본 배열과 새 배열 모두에 영향을 미친다.
깊은 복사 하는방법
JSON.parse(JSON.stringify(array))
사용immerjs
깊은 복사 라이브러리 사용const arr = [5, 6, 2];
const sortedArr = arr.sort((a, b) => b - a);
console.log(arr); // [6, 5 ,2]
console.log(sortedArr); // [6, 5, 2]
toSorted
메소드가 새로 나왔다 (원본 배열 복사도 같이 해줌)
이렇게 유용한 정보를 공유해주셔서 감사합니다.