let str;
str = 'test'
값을 바로 변수에 대입하지 않는 이유? → 자유로운 데이터 변환, 메모리의 효율적 관리를 위함. (자리 이동 최소화)
이름 : str 데이터 : @5004
?이렇게 저장되어있는 것이 아니고
코드와 사용자는 var str은 @1002 를 말하는 거라고 그냥 쓰는것일 뿐..
실제 공간에는 주소값만 있음. 변수명은 코드 내에서의 식별자일 뿐 저장X
const int y = 10;
이라면, y = 20;
은 불가능합니다.상수는 '값 자체'와 '참조' 모두 변경할 수 없다는 점에서 제한이 있고, 변수는 '값'을 자유롭게 변경할 수 있다
그럼 안 쓰게 된 데이터는 어디로 가냐 ? → 가비지 컬렉터가 더이상 참조되지 않는 공간을 탐색하여 삭제함
obj1을 복사한 obj2의 원소를 변경하면 → obj도 똑같은 주소를 바라보고 있기에 obj1까지 변경된다
그렇기에, 가변하는 객체의 복사는 주의해야한다.
그래서 객체의 프로퍼티에 접근해서 값을 변경하지 말고 객체 자체를 변경하면 obj1과 obj2는 다른 공간을 바라보기에 서로 독립적이 된다.
var a = 1; var b=1;일 때, 1이 저장된 주소값을 a, b 둘 다 바라보고 있게 된다는 뜻?
일리가 없을텐데…
원시 타입(number, string, boolean 등)의 경우,
동일한 값이라도 각각의 변수가 서로 다른 메모리 공간에 값을 저장한다.
실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
콜 스택
내가 코드를 짜면, 그걸 스택으로 쌓기 때문에 JS는 코드의 환경 및 순서를 보장?
→ 실행 컨텍스트 쉽게 말해서 실행 순서(흐름) 인듯. 내가 짜면 실행 순서에 따라 스택에 쌓이고 그걸 콜 스택이라고 부른다.
컨텍스트의 구성
전역공간, eval()함수 등 컨텍스트를 구성하는 방법엔 여러가지가있긴한데?
함수 ← 가 흔하게 실행 컨텍스트를 구성하는 방법.
함수 실행 순서를 말하는듯?
특정 실행 컨텍스트가 활성화되는 시점 == 스택의 최상단에 위치할 때
실행 컨텍스트에는 어떤 내용이 있는가
크게 3가지 1. VariableEnvironment, 3. LexicalEncironment 3. ThisBinding
VariableEnvironment(VE)
현재 컨텍스트 내의 식별자 정보(=record)
아까 변수명 자체가 식별자다! 라고 했으니까, var a
같은거
외부 환경 정보(Outer)
선언 시점 LexicalEncironment의 Snapshot
LexicalEncironment (LE)
ThisBinding
VE와 LE는 snapshot 유지 여부의 차이만 있다.
record → 호이스팅
식별자 정보를 수집할 때 호이스팅 개념이 나온다. 호이스팅은 가상 개념인 점 참고
호이스팅 : 식별자를 수집하고, 위로 끌어올린다.
함수 선언문, 함수명 a가 곧 변수명
function a() {...};
함수 표현식, func을 별도의 변수에 할당하는 경우.
1. 익명함수표현식
var b = () => {...};
2. 기명함수표현식 (활용성 거의 x)
var c = function d() {...};
c(); <- 이건 실행
d(); <- 이건 에러
호이스팅 과정에서, 함수 선언문은 그 자체가 식별자이기 때문에 함수 자체가 위로 끌어올려지는 반면, 함수 표현식은 다른 변수와 같이 var b
만 끌어올려진다.
함수 선언식보다 함수 표현식을 사용하는게 동명의 함수 이슈 또는 실행 범위 문제에서 더 안전하다?
Outer
실행 컨텍스트에서 바로 이전 스택의 LexicalEnvironment가 현재 스택의 Outer가 된다.
즉, 이전 환경을 참조하게 된다. 이후의 환경(이후의 스택)은 참조할 수 없다. 상위 스코프에서만 참조할 수 있다는 원리
→ 스코프 체이닝
스코프 체이닝(Scope Chaining):
각각의 실행 컨텍스트는 LE를 갖고 있고, LE에는 Record와 Outer을 가지고 있는데, LE는 현재 스코프의 LE(현재 스코프에 선언된 변수와 함수에 대한 정보), Outer은 상위 스코프의 LE를 참조한다.
this
this는 실행 컨텍스트가 생성될 때(=바인드 될 때) 결정된다.
(=함수를 호출할 때 결정된다)
전역 환경에서 this는 → node(global), 브라우저(window)
함수 vs 메서드
엄연한 차이가 존재!
독립성
, 호출 주체가 O/X 로 나뉜다함수는 그 자체로서 독립적인 기능을 하고 호출이 가능하지만
메서드는 자신을 호출한 대상 객체에 대한 동작을 수행하는 종속성이 있다.
함수는 this가 전역 객체 (호출의 주체를 명시할 수 없기 때문)
메서드는 this가 호출의 주체(메서드를 소유한 객체)가 된다.
내가 오해한 점
this는 상위 주체를 가르키는 건가? → X
무조건 상위 주체라고 하면 틀리고 “상황에 따라 다르다“ 라는 표현이 맞다고 함
전역 스코프에서 this → window(브라우저)
함수 내부에서 (엄격 모드가 아닐 때), 호출 주체가 없으면 this
는 전역 객체(브라우저의 경우 window
, Node.js에서는 global
)
엄격 모드에서는 함수 내부에서 호출 주체가 없으면 this
는 undefined
가 된다.
메소드에서는 호출한 주체 단, 메서드 내의 함수의 this
는 전역객체
프로그래머스 - 최소 직사각형 문제
이것은 난리의 흔적...
아래는 오답 코드
function solution(sizes) {
let maxCardSize = 0;
let tempArr = [];
//제일 큰 카드 사이즈 찾기
for(const card of sizes){
let cardSizes = card[0] * card[1];
maxCardSize = (cardSizes > maxCardSize) ? cardSizes : maxCardSize;
}
for(let i =0; i<sizes.length;i++){
for(let k =0; k<sizes.length;k++){
let cardSize =sizes[i][0]*sizes[k][1];
if(cardSize >= maxCardSize)
tempArr.push(cardSize);
}
}
return Math.min(...tempArr);
}
가장 큰 카드의 사이즈를 구하고, 이것보다 더 큰 크기가 나오는 조합 중 최소값을 찾으면 된다고 생각했는데 일부의 케이스에만 정답이 나오고 많은 케이스에서 오답... 이 나온 코드다.
아 풀다가 문제의 접근법이 틀려먹은 것 같아 결국 gpt에게 도움 요청
가로 세로 중 큰 값을 한 열로 모는 것이 포인트였다...
이 아이디어가 그렇게 생각이 안났다
가장 큰 값을 구하고... 그리고 그 큰 값이 있는 배열의 다른 원소보다 큰... <- 이러고 한참을 뻘짓했었다^^
이것은 통과한 코드 ^^v
function solution(sizes) {
const Sorted = [];
let maxWidth = 0;
let maxHeight = 0;
// 가장 긴 값을 한 열로 몰기
for (const card of sizes) {
if (card[1] > card[0]) {
//구조분해할당 사용
[card[0], card[1]] = [card[1], card[0]];
}
Sorted.push(card);
}
// Sorted.forEach(card => console.log(card)); // 각각의 배열 요소를 출력
for(const card of Sorted){
maxWidth = (card[0]>maxWidth)? card[0]:maxWidth;
maxHeight = (card[1]>maxHeight)? card[1]:maxHeight;
}
return maxWidth*maxHeight
}
중간은 확인용 콘솔....
이렇게 간단하게 구현할 수 있는 문제였구나~
참고로 저번에 배운 구조분해할당(비구조화 할당) 써봤다. temp 써서 하려다가 다시 찾아보고 적용했다. ES6문법에 익숙해지도록 많이 써봐야지.
이번 문제는 gpt가 거의 풀어준거나 마찬가지라 약간 찝찝한 기분을 지울 수 없지만
앞으로 더 열심히 알고리즘 공부하는걸로...
gpt 사용하셨다고 해도 본인의 언어로 내용을 풀어 적어서 til 잘 작성해 주셨내요! 이렇게 계속 알고리즘이나 코드짜는 흐름을 배우는게 초반에는 정말 중요해서, 잘하고 있으십니다!(。・ω・。)