0831 <JavaScript Deep Dive> 스터디

dev_sang·2022년 9월 5일
0

STUDY

목록 보기
2/2

1. 종한

다음 코드의 실행 결과를 예측해보고 그 이유를 설명해보세요.

1-1. var

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // ?
bar(); // ?
let x = 1;

function foo() {
  let x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // ?
bar(); // ?

종한님 답:
→ var, let (const도 동일) 모두 동일하게 foo, bar 에서 1 출력
→ JS는 렉시컬 스코프 (함수를 어디서 정의했는지에 따라 함수의 상위 스코프 결정)
따라서 bar 함수는 정의된 곳의 스코프를 따른다 (전역 변수)
전역변수 x = 1 이므로 bar 함수가 foo 함수 (전역보다 하위 스코프)에서 호출되더라도 1을 리턴한다


내 답:
출력값은 모두 1

위 두 코드의 함수들은 모두 전역 변수인 x를 참조하고 있다. 전역 변수의 스코프는 코드 전체에 해당합니다. 따라서 코드 전제의 어디서든지 전역변수 x를 참조할 수 있습니다.
foo함수 안의 지역변수 x의 스코프는 foo함수 몸체 내부에만 한정됩니다. 따라서 bar함수는 foo함수의 지역변수 x를 참조할 수 없습니다.
때문에 모든 출력값은 전역 변수 x의 값인 1이 됩니다.



2. 상지 ME

함수 선언문으로 정의한 함수는 함수 호이스팅이 일어나고, 함수 표현식으로 정의한 함수는 변수 호이스팅이 일어납니다. 그 이유에 대해 설명해주세요.

console.dir(함수이름1) // 함수이름1(x, y)
console.dir(식별자) // undefined

console.log(함수이름1(1, 3)) // 4
console.log(식별자(1, 3)) // 식별자 is not a function

// 함수 선언문
function 함수이름1(x, y){
	return x + y;
}

//함수 표현식
var 식별자 = function 함수이름2(x, y) {
	return x+y;
}

내 답:
자바스크립트 엔진은 런타임 이전에 모든 선언문을 먼저 실행시킵니다. 그럼 함수 선언문도 실행 되겠죠? 그럼 런타임 이전에 함수 객체가 먼저 생성되는 것입니다. 그리고 JS엔진은 참 센스있게도(?) 함수 이름과 동일한 이름의 식별자를 생성해 이 식별자에 함수 객체를 할당합니다. 이렇게 되면 런타임에는 이미 함수 객체 생성과 함수 이름과 동일한 시별자에 함수 객체 할당까지 완료된 상태가 되는 것이죠. 따라서 함수 선언문 이전에 함수를 참조할 수 있고 호출할 수도 있게 되는 것이고 이렇게 함수 호이스팅이 일어납니다.

함수 표현식은 변수에 함수 리터럴 문이 할당되는 것입니다. 따라서 함수 표현식은 함수 호이스팅이 아닌 변수 호이스팅이 일어납니다. 즉 변수를 선언하고 그 변수에 함수 리터럴을 할당하는 것이죠 변수 선언 또한 런타임 이전에 실행되고 이때 변수의 경우는 undefined로 초기화 됩니다. 즉 함수 표현식의 변수는 undefined로 초기화 되었다가 런타임에 함수 표현식이 변수에 할당될 때 평가되어 함수 객체가 됩니다. 그래서 함수 표현식으으로 함수를 정의하면 변수 호이스팅이 발생하는 입니다.



3. 형빈

단답형: JS에서 함수는 객체입니다. 하지만 둘간의 차이점이 있는데, 일반객체와 함수의 차이점에대해서 말해주세요(p.158)

형빈님 답: 일반 객체는 호출 할 수 없지만 함수는 호출이 가능하다.

내 답:
(+ 덧붙여 설명하기)
자바스크립트의 함수는 일급 객체입니다. 여기서 일반 객체와 일급 객체에 차이점을 짚고 넘어가지 않을 수 없을 듯 합니다. 먼저 일급 객체란 무엇일까요?

일급객체(First-class Object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. [위키백과]

MDN을 살펴볼까요?

'변수'수 처럼 취급 가능하다는 것은 어떤 의미일 까요? 일급 객체의 조건은 아래와 같습니다.
1. 무명의 리터럴로 생성할 수 있다. (즉 런타임에 생성이 가능하다.)
2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
3. 함수의 매개변수로 전달할 수 있다.
4. 함수의 반환값으로 사용할 수 있다.

즉 자바스크립트에서는 함수를 데이터(string, number, boolean, array, object)를 다루듯이 다룰 수 있다는 것입니다. 자바스크립트의 함수는 일반 객체에는 없는 위와같은 특징들을 가지고 있습니다.

다음의 코드를 실행 결과를 예측하고, 그 이유를 설명하시오.

function deepDive(){
 var x = 1;
 var x = 2;
console.log(x);
} 
deepDive(); // 2
function deepDive2(){
 let x = 1;
 let x = 2;
console.log(x); //syntaxError
}
deepDive2();

형빈님 답: var키워드는 중복선언이 허용된다.

내 답: var키워드로 선언된 변수는 재할당과 중복 선언이 모두 가능합니다. 그러나 let키워드로 선언된 변수는 재할당은 가능하지면 중복선언은 불가합니다. 따라서 두번째 코드에서 SyntaxError가 안나오게 하려면 아래와 같이 코드를 수정하면 됩니다.

function deepDive2(){
 let x = 1;
 x = 2;
console.log(x);
}
deepDive2();


4. 형석

다음 코드를 읽고 실행결과와 그 이유를 설명해주세요.

//ARR배열에서 2인 값을 찾아내는 함수를 각각 filter와 for를 이용하여 작성하였습니다.

const ARR = [1,2,3]

const filter1 = ARR.filter((item)=> item === 2)

const testFunc = () =>{
 for(let i=0; i<ARR.length; i++){
  if(ARR[i]===2) return ARR[i]
  }
}

const filter2 = testFunc()

console.log(filter1 === filter2)
// 아래 결과는 여러분과 함께 의견 공유하고 싶은 문제
console.log(filter1 == filter2)

형석님 답:
filter의 경우 결과값으로 무조건 배열을 반환하게 된다.
따라서 첫번째 console은 [2] === 2 이므로 false
두번째 console의 경우 타입 비교 없이 [2] == 2를 하게되는데 자바스크립트가 임의로 [2]를 2로 판단하여 2 == 2를 비교하게 되어 true가 나오게된다

내 정리:
잘 알지 못했던 부분!
위 코드에서 filter1 과 filter2를 찍어보면 각각

이렇게 나온다. filter매서드의 반환값은 항상 배열이라는 것!(filter1)

그래서 console.log(filter1 === filter2)의 값은 false 가 된다.
반면 console.log(filter1 == filter2)에서 ==연산자의 경우 두 피연산자 값의 타입이 다를 경우 임의로 타입 변환을 한 후에 값을 비교한다. 즉 타입을 비교하지 않고 값만 비교하는 것. 그래서 ture 값이 출력된다.



5. 은빈

다음 코드를 읽고 실행 결과와 그 이유를 설명해주세요.

var person1 = {
	name: 'Lee'
};

var person2 = {
	name: 'Lee'
};

console.log(person1 === person2) // ?
console.log(person1.name === person2.name) // ?

은빈님 답:
person1 변수와 person2 변수가 가리키는 객체는 비록 내용은 같지만 다른 메모리에 저장된 별개의 객체다. 즉 두 변수의 참조 값은 전혀 다른 값이다. -> false
하지만 프로퍼티 값을 참고하는 person1.name과 person2.name은 값으로 평가될 수 있는 표현식이다. 두 표현식 모두 원시 값 'Lee'로 평가된다. → true

ISSUES

1) 순수 함수와 비순수 함수

2) React side effect

React Hooks: useEffect 사용법

[React] Side Effect란?

배운점

비순수함수는 side effect를 불러일으켜서 의도치 않은 코드 변화를 가져올 수 있지만 마냥 나쁜것만은 아님. axios나 useState 처럼 의도적으로 비순수함수 컨셉을 차용하는 사례가 있음

profile
There is no reason for not trying.

0개의 댓글