스코프,클로져
코드에서 let으로 선언된 i는 각각의 setTimeout() 함수에서 새로운 변수가 생성됩니다. 이러한 변수 생성 방식을 블록 스코프라고 합니다. 따라서 setTimeout() 함수에서 사용되는 i 값은 이전 값에 의존하지 않으며, for 루프의 값에 대한 복사 본을 사용합니다.
루프의 값에 대한 복사본?
**let**으로 선언된 변수의 경우, 각각의 setTimeout() 함수에서 새로운 변수가 생성됩니다. 이때 생성된 변수는 for 루프에서의 값에 대한 복사본을 가지고 있습니다. 이러한 변수 생성 방식을 블록 스코프라고 합니다.
즉, for 루프 내에서 **let**으로 선언된 변수는 블록 스코프를 갖게 되어, 각각의 블록에서 새로운 변수가 생성되며, 이때 생성된 변수는 for 루프에서의 값에 대한 복사본을 가지고 있습니다. 따라서 setTimeout() 함수에서 사용되는 i 값은 이전 값에 의존하지 않으며, for 루프의 값에 대한 복사본을 사용합니다.
반면에 **var**로 선언된 변수는 함수 스코프를 갖게 되므로, for 루프에서 생성된 변수는 전역 스코프에서 유효한 하나의 변수를 참조합니다. 따라서 setTimeout() 함수에서 **var**로 선언된 i 값은, setTimeout() 함수가 실행되는 시점에서의 i 값, 즉 마지막으로 할당된 값(10)을 참조하게 됩니다. 이러한 문제를 클로저 문제라고 합니다.
반복문 내에서 settimeout 함수가 실행될때 블록 스코프는 값에 대한 복사본으로 선언되어진다면. 그래서 i가 5까지 반복한다했을때 각각의 수가 변수로 선언된다 한다면
var i 로 선언된 i는 함수 스코프로 전역에 유효한 변수 하나가 생성되는것이기때문에 settimeout의 처리뒤에 찍힐 수는 5뿐이다.
예제 코드
function fun2(){
for (let i = 0; i < 5; i++) {
//블록 스코프
if(true)
{
// var는 함수 스코프
// 함수 스코프에 선언된것
var a=45;
// 블록 스코프로 let을 선언
let b = 50;
}
// 호출이 된다. 접근 o var는 함수 스코프이고
console.log(a);
// 호출이 안된다. 접근 x let은 블록 스코프니까
console.log(b);
}
}
이터러블
// 이러블 과 이터레이터 ES6에 추가되었고
// 이터러블은 반복이 가능한 객체라는 뜻.
// 이터러블을 반복하는 반복문
// forEach : 배열을 순회하면서 아이템을 반복실행한다. 아이템의 갯수만큼
// for of : 이터러블의 아이템을 반복실행한다.
// 등등
// symbol : ES6 에 추가된 원시타입
// 값이 겹치지않고
// 선언되고 변경이 불가능.
// 객체의 속성에 접근하기위해서 사용.
// 반복자 symbol.iterator : 이터러블 객체를 나타내는 매서드 이름으로 사용
// 해당 객체가 이터러블 이라는것.
// symbol.iterator 메소드가 이터레이터 객체를 반환한다.
// 이터레이터 : 이터러블 객체의 각 아이템의 접근하기 위한 기능
// 이터레이터 객체의 next 메소드가있어요.
// next 메소드를 사용하면 {value, done} 객체를 반환한다.
// 반복중인 아이템을 value에 주고 done은 끝났는지를 알려준다.
// 이터레이터는 이터러블(반복 가능한 객체)를 순차적으로 접근할수 있는 기능
// 자바스크립트의 배열이나 문자열 등등도 이터러블이라는것.
// 구조간단히 만등
// const Arr =[1,2,3,4,5];
// const objIter={
// index:0,
// next : function(){
// if(this.index < Arr.length)
// {
// // done 마지막 요소가 맞니??
// return {value: Arr[this.index++],done:false}
// }
// else{
// // done 마지막 요소 끝
// return{done:true};
// }
// }
// }
// let result = objIter.next();
// console.log(result.value, result.done);
// result = objIter.next();
// console.log(result.value,result.done);
// result = objIter.next();
// console.log(result.value,result.done);
// result = objIter.next();
// console.log(result.value,result.done);
// result = objIter.next();
// console.log(result.done);
// 이터러블 작성
const Arr2=[1,2,3,4,5];
// symbol은 객체의 속성에 접근한느데 사용한다했음.
// 객체의 속성으로 접근하는데 symbol.iterator
// Arr2[Symbol.iterator]() 이터레이터 객체를반환해준다.
// const iter2 = Arr2[Symbol.iterator]();
// let result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// result2= iter2.next();
// console.log(result2);
// 어려운 개념?
// 값을 바꾸는데 편하고 적합한 함수
// reduce 함수 값을 바꾸는데 적합한 함수
// 예) 이터러블 이터레이터를 따르는 이터레이터 값이 value 가
// 숫자라면 문자로도 바꿀수있고 여러가지 방법으로 값을 바꿀수있다
// 배열이나 객체와 같은 데이털르 줄일수있따.
const Arr3=[1,2,30,4,5,15,10];
//reduce 메소드
// 첫번쨰 매개변수가 콜백함수, 두번째 매개변수가 초기값을 넣어준다.
// 배열의 0번이 들어간다. 초기값을 안넣으면
//두 값을 더하면서 반환시키는 기능
// const temp3= Arr3.reduce(function(acc,value){
// // acc 이전 결과값 return 된
// console.log("acc" ,acc);
// console.log("value" ,value);
// //return "이전 결과값"
// console.log(acc+value);
// if (acc===33)
// {
// return 50
// }else{
// return acc + value;
// }
// },0);
// 배열을 순회하면서 제일큰값을 반환시켜주는기능
const max = Arr3.reduce(function(acc,value){
console.log("acc ",acc);
console.log("val ",value);
// 두개를 비교해서 값이큰지 확인하고 큰수를 반환
return acc>value?acc:value;
});
console.log(max);
// 배열을 순회하면서 제일 작은 값을 반환시켜줌
const min= Arr3.reduce(function(acc,value){
// 두개를 비교해서 반환값보다 작은지 비교
return acc<value ? acc: value;
}
)
console.log(min);
이터러블에 대한 gpt의 대답
Iterable은 for...of 루프를 사용하여 반복할 수 있는 객체입니다. Iterable 객체는 Symbol.iterator 속성을 갖고 있으며, 이 속성은 Iterator 객체를 반환합니다. Iterator 객체는 next() 메서드를 갖고 있으며, 호출될 때마다 IteratorResult 객체를 반환합니다.
IteratorResult 객체는 두 개의 속성을 갖습니다. value 속성은 현재 값이며, done 속성은 Iterator 객체의 마지막 값을 반환했는지 여부를 나타냅니다.
따라서, Iterable 객체와 Iterator 객체는 JavaScript에서 반복 작업을 수행할 때 사용됩니다. 예를 들어, 배열, 문자열, Set, Map 등의 객체는 모두 Iterable이며, 이러한 객체에서 for...of 루프를 사용하여 값을 반복적으로 처리할 수 있습니다.
이러한 Iterable 객체를 만들고자 할 때는, Symbol.iterator 메서드를 객체 내에 정의하여 Iterator 객체를 반환하도록 구현하면 됩니다. 이를 통해 객체를 Iterable 객체로 만들 수 있습니다.
내가 다시정리한것
iterable은 반복가능한 객체 ,이것을 가지는 객체는 배열,문자열,set 등
iterator 은 symbol.iterator속성 가지고있다. 이 속성은 iterator 객체를 반환한다.
그 객체 iterator 객체는 next 속성을가지고 호출될때에 IteratorResult 객체를 반환하는데
이객체가 value , done 속성을 가진다
value는 현재 값 done은 마지막 값을 반환했는지 여부를 보여준다.
예를 들어 Arr4라는 배열이 있다 가정한다. 그리고 그 배열은 내장 메서드인 symbol.iterator을 갖고있다.
Arr4symbol.iterator 이런식으로 호출하는것은 해당 배열의 이터레이터 객체를 반환하는것이다.
위에 작성했던것과 같이 iterator 객체는 next 속성을 가진다. next를 호출해서 반환하면 iteratorResult를 반환하고 그 안에 value,done 속성이있다.
배열의 reduce
배열의 reduce는매겨변수로 받은 콜백을 실행하며 최종결과값을 반환한다.
reduce 콜백함수의 첫매개변수는 누적값 두번쨰 매개변수로 현재 요소값 세번쨰는 현재 요소의 인덱스갓 네번쨰로는 배열그자체를 받는다.
배열의 for of
'for...of' 루프는 배열, 문자열, 맵, 세트 등과 같은 반복 가능한 객체의 요소를 반복할 수 있는 JavaScript의 최신 반복문입니다. 컬렉션의 요소를 반복하고 싶을 때 기존의 'for' 루프에 비해 더 간단하고 깨끗한 구문을 제공합니다.
'for...of' 루프는 모든 이터러블 객체와 함께 작동하며 인덱스나 길이를 확인할 필요 없이 이터러블의 각 요소를 자동으로 반복합니다
반복가능한 데이터를 상대로 사용할떄 적합하다. {} 안에 어떤 가공이 가능한듯하다 python의 for문하고 비슷한듯?
const numbers = [1, 2, 3, 4, 5];
for (const num of numbers) {
console.log(num);
}
// 산출결과
1
2
3
4
5
const str = 'Hello';
for (const char of str) {
console.log(char);
}
H
e
l
l
o
배열의 map
// 기본형
const newArray = array.map((currentValue, index, array) => {
// Transformation logic here
return transformedValue;
});
currentValue: 배열에서 처리 중인 현재 요소입니다.
index: 배열에서 현재 요소의 인덱스(선택 사항).
array: 배열 map()이 호출되었습니다(선택 사항).
예시1
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((num) => {
return num * 2;
});
console.log(doubledNumbers);
// Output: [2, 4, 6, 8, 10]
예시2
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((num) => num * 2);
console.log(doubledNumbers);
// Output: [2, 4, 6, 8, 10]
예시3
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const userNames = users.map((user) => user.name);
console.log(userNames);
// Output: ["Alice", "Bob", "Charlie"]
map() 메서드는 원래 배열을 수정하지 않는다는 점에 유의해야 합니다. 대신 변환된 값이 포함된 새 배열을 반환합니다. 원래 배열을 제자리에서 수정하려면 forEach()와 같은 다른 배열 메서드를 사용하거나 인덱스 기반 할당을 사용하여 요소를 직접 업데이트할 수 있습니다.
배열의 foreach
map() 메서드와 달리 forEach() 메서드는 새 배열이나 값을 반환하지 않습니다. 주로 로깅, DOM 업데이트 또는 새 배열 생성과 관련되지 않은 기타 작업 수행과 같이 배열의 각 요소에 대해 일부 부작용을 수행하려는 경우에 사용됩니다.
한 가지 중요한 점은 반복을 조기에 종료하거나 건너뛰기 위해 forEach() 루프 내에서 break 또는 continue 문을 사용할 수 없다는 것입니다. 조기 종료 또는 조건부 반복을 수행해야 하는 경우 기존 for 루프 또는 some() 또는 every() 메서드를 사용할 수 있습니다.
forEach() 메서드는 JavaScript의 배열에 사용할 수 있으며 문자열, 맵 또는 세트와 같은 다른 반복 가능한 객체에는 사용할 수 없습니다. 다른 반복 가능한 객체의 경우 특정 데이터 구조에 적합한 다른 반복 방법을 사용할 수 있습니다.
'언어 > js' 카테고리의 다른 글
| 20230330 promise객체 then catch ,async await ,try-catch문,정규식 재귀함수 (0) | 2023.07.20 |
|---|---|
| 20230329 콜백 자율공부 (0) | 2023.07.20 |
| 20230328 스프레드 연산자. (0) | 2023.07.20 |
| 20230327 구조분해 할당, swipe (0) | 2023.07.20 |
| 쿠키의 이해2 (0) | 2023.07.20 |