21.08.13

하소희·2021년 8월 13일
0

개발일지

목록 보기
38/56

학습 내용

if 조건문과 전역/지역변수, 스코프에 대한 내용을 배웠다.

210813 자바 스크립트 개념 코드

IF 조건문

: 어떠한 논리 구조를 만든다. 영어 단어 그대로 '만약 ~ 한다면 ~해라'
if(조건작성) { }
소괄호 안의 조건이 참일 경우 중괄호 안의 구문이 실행된다. if(true) { } 소괄호 안에 true라고 적어도 중괄호 부분 실행.. 소괄호 안에서 true/false만 인식한다.
조건이 거짓이라면 아무것도 출력되지 않는다.

var a = 20;
var b = 40;

if(a < b) {
	console.log("a는 b보다 작다");
}

출력 결과는 a는 b보다 작다

그런데 거짓인 경우엔 거짓인 상태를 사용자들에게 인식시켜줘야한다. 예를 들어 아이디 비번을 입력했는데 틀렸으면 틀렸다고 말을 해줘야 한다.

-> 이걸 담당하는 게 else문

if(a > b) {
	console.log("a는 b보다 크다");
} else {
	console.log("a는 b보다 작다");
}

else문은 if문이 거짓일 경우에만 실행되는 구문이다.

else if문
: 여러개의 조건을 설정할 때 사용

var a = 20;
var b = 40;
var c = 60;

if(a > b)  {
	console.log("a는 b보다 크다");
} else if(b > c) {
	console.log("b는 c보다 크다");
} else if(a < c) {
	console.log("a는 c보다 작다");
} else if(b < c) {
	console.log("b는 c보다 작다");
} else {
	console.log("모든 조건을 만족하지 않는다");
}

출력 결과는 a는 c보다 작다
  • 또다른 조건을 추가하고 싶으면 위와 같이 else if를 붙이면 된다. 만약 이도저도 아닌 모든 조건이 충족 안할 경우를 적으려면 맨 마지막에 else로 위처럼 적으면 된다.

else if 주의점

  • 조건들 중에서 여러개의 참이 존재할 경우, 가장 먼저 나오는 참만 실행시킨다. 위의 예시에서 b < c도 참이지만 출력된 것은 a는 c보다 작다다. 이후 조건은 보지도 않고 그 즉시 실행이 정지된다.

중첩 if문
: if문 안에 if문을 넣는 구조, 보다 탄탄한 논리 구조를 만들 수 있다.

var a = 20;
var b = 20;

if(a > b) {
	console.log("a는 b보다 크다");
} else {
	console.log("a는 b보다 작다");
}

a와 b가 같을 경우 a>b는 거짓이므로 else의 경우로 들어간다. 하지만 a가 b보다 작은 것은 아니다. 일종의 버그가 발생하는 것이다. 이런 버그를 방지하기 위해 조건을 좀 더 꼼꼼하게 작성해야 한다. 이럴 때 사용하는게 중첩 if문

if(a !== b) {

} else {
	console.log("a와 b는 같다");
}

먼저 a와 b가 같은지, 다른지부터 따진다. 대전제로 깔아주는 셈이다. 그 다음에 else를 따진다. else에선 a와 b가 같은 경우를 보는 것이다.

if(a !== b) {

이부분→ if(a > b) {
	  console.log("a는 b보다 크다");
	} else {
	  console.log("a는 b보다 작다");
	}  ←여기까지

} else {
	  console.log("a와 b는 같다");
}

변수를 변경하면서 출력 결과를 확인하자

체크해둔 부분
a와 b가 다르다면 a가 b보다 큰지? 만약 크지 않다면(else) a가 b보다 크지 않은 경우, 즉 a가 b보다 작을 때를 확인할 것이다. 같은 경우는 이미 대전제에서 확인하고 들어왔기 때문에 안쪽에선 확인하지 않는다.


- 실무 tip!
.
★거짓이 되는 상황
: 굉장히 많이 사용되므로 꼭 기억하자

if(false) {
	console.log("참!!!");
} else {
	console.log("거짓!!!");
}
거짓!!!이 출력된다

조건으로 false 외의 다른 값을 입력한 경우에도 거짓이 출력될 수 있다.
그런데 조건에 그냥 글자로 "Hello"를 적었는데 참으로 인식해서 값을 출력한다.
예시 - 사용자가 로그인하는데 아이디 입력을 안 했다. 그 상태를 js에서 빈문자열로 인식한다. 이럴 때 사용자에게 else문으로 아이디를 기입하라고 인지시켜줘야 하기 때문에 빈 문자열로 거짓이 되는 조건을 알아둬야 한다.
.
※ false 외의 다른 값
: 빈문자열 ("",'') 0 null undefined

  • 빈문자열은 큰따옴표나 작은따옴표 안에 아무 데이터도 넣지 않은 상태를 말한다.
  • 0 이외(음수 포함)는 다 참으로 인식
  • undefined는 변수에 아무런 값을 넣지 않았을 때 나타난다. 아무런 값을 갖지 않는 변수를 조건에 넣을 경우 거짓으로 출력된다.

삼항 연산자
일종의 조건문으로 조건문과 유사하게 동작, if else문 같은 구조를 만들 때 쓴다. if와 else조건문의 중괄호 안 구문이 1줄 짜리로, 단순할 경우에 사용. 2줄 이상부터는 그냥 if else

var age = 15;

if(age >= 18) {
	console.log("성인");
} else {
	console.log("어린이");
}

위의 조건문을 삼항 연산자로 적을 경우

var result = (age >= 18) ? "성인" : "어린이";
console.log(result);
  1. = 뒤에 조건을 적는다.
  2. 조건이 참일 경우 ? 안에 있는 구문을 result에 할당
  3. 조건이 거짓일 경우 콜론(:) 안에 있는 구문을 result에 할당

조건문 응용

var userId = prompt("아이디를 입력해 주세요.");
var userPw = prompt("비밀번호를 입력해 주세요.");

console.log(userId);
console.log(userPw);

출력 결과를 보면 이렇게 팝업이 뜬다.

팝업은 브라우저에서 기본적으로 제공하는 것으로 prompt라는 메서드를 써서 뜨는 것이다. 팝업 디자인은 브라우저마다 적용된 css가 달라서 다르다. prompt 메서드는 오로지 브라우저 환경에서만 동작된다. 사용자에게 어떤 값을 전달받는 팝업을 띄운다. 모든 브라우저에서 사용 가능하다.

아이디, 비번을 차례로 입력하면 그 값이 userId, userPw에 각각 할당된다.

아무것도 입력하지 않는다면 빈 문자열 전달

var userId = prompt("아이디를 입력해 주세요.");
var userPw = prompt("비밀번호를 입력해 주세요.");

if(userId === "younghee" && userPw === "12345") {
	alert("로그인되었습니다.");
} else {
	alert("아이디 또는 비밀번호가 틀렸습니다.");
}
  • 조건에 &&연산자를 사용했기 때문에 앞뒤 모두 참이어야 true로 반환된다. 둘 중 하나라도 거짓이면 false를 반환하기 때문에 else문이 실행되게 만들어준 것이다.
  • alert 팝업은 따로 입력하는 정보 없이 사용자에게 지금 어떤 상태인지를 인지시켜 줄 때 쓴다.

만약에 비번 부분을 문자열이 아니라 그냥 숫자로 했을 경우에

if(userId === "younghee" && userPw === 12345) {
	alert("로그인되었습니다.");
} else {
	alert("아이디 또는 비밀번호가 틀렸습니다.");
}

비번으로 12345를 입력해도 틀렸다고 뜬다. prompt로 전달받은 값들은 데이터 타입이 모두 string이라서 그렇다.(console.log(typeof userPw); 찍어보면 알 수 있다)

userPw === 12345 : 문자열과 숫자열의 데이터타입까지 비교하고 있기 때문에 false로 반환
무조건 숫자로 비교하고 싶다면 문자로 전달된 숫자를 숫자 데이터 타입(정수형)으로 변경해야 한다-> parseInt

if(userId === "younghee" && parseInt(userPw) === 12345) {
	alert("로그인되었습니다.");
} else {
	alert("아이디 또는 비밀번호가 틀렸습니다.");
}

전역변수, 지역변수

이후의 내용들과 다 연결되어있다. 함수를 기준으로 전역과 지역이 구분된다. 먼저 개념을 쉽게 설명하자면 이렇다.

전역 변수 : 모든 범위에 영향력을 행사할 수 있는 변수.
예) 지구, 모든 국가에 적용되는 법
지역 변수 : 특정 범위에만 영향력 주는 변수
예) 지구 안의 각 나라들, 국가별 법은 국가 내부에서만 영향력

var globalV = "전역변수";

function func() {
	var localV = "지역변수";

	console.log(globalV);
	console.log(localV);
}

//func(); <- 함수 실행시 전역변수, 지역변수가 출력된다.
//이번에는 함수 밖에서 콘솔로그로 각 변수를 찍어본다.

console.log(globalV);
console.log(localV);

함수 밖에서 각 변수를 찍어보면 출력 결과가 전역변수는 나오지만 localV의 결과는 아래처럼 에러가 뜬다.
Uncaught ReferenceError: localV is not defined

전역 변수 : 함수 안쪽, 바깥쪽 모든 영역에 다 영향력을 발휘한다.
지역 변수 : 함수 안에서 만들어진 변수, 함수 안에서만 영향력을 발휘한다.

그래서 함수 밖에서 localV를 찾으면 안 나오는 것이다. 함수를 기준으로 전역과 지역이 구분된다.
-> 여기까지는 과거의 자바 스크립트

ES6라고 불리는 최근 버전의 js는 let, const를 이용해서 변수를 만들 수 있다. var 대신 let, const를 사용해서 만들면 전역, 지역 변수를 구분 짓는 기준점이 달라진다. 현재 입문 단계라서 자세히 배우진 않고 이런 게 있다 정도로만 알고 넘어가면 된다.

옛날 버전 js를 알아야 최신 js의 키워드나 개념들을 무리없이 습득할 수 있다.

전역/지역 변수 만들 때 주의점

var gv = "전역변수";

function func() {
	var gv = "지역변수";
	console.log(gv);
}

func();

console.log(gv);

동일한 변수명이 함수 안과 밖에 모두 있다.

출력 결과다. 
지역변수
전역변수

※ 실무에선 같은 변수명을 사용하는 경우가 거의 없다.

함수 안쪽의 console.log(gv);는 함수 안에서 만들어진 gv를 출력, 함수 바깥의 console.log(gv);는 함수 안에는 접근할 수 없다. 이미 함수 안에 gv가 있기 때문에. 그래서 함수 밖에 gv가 있는지 탐색하고, gv가 존재하기 때문에 그 값인 전역변수를 출력했다.

var gv = "전역변수";

function func() {
	gv = "지역변수";  <- var 키워드 없앨 경우
	console.log(gv);
}

func();

console.log(gv);

결과는 둘 다 지역변수로 출력
함수 안에서 var 키워드를 쓰지 않아서 gv가 지역변수가 된 게 아니라 함수 밖에 있는 전역 변수인 gv의 값을 바꾸는 행동이 된 것이다.

이전에 배운 변수 안의 값을 변경하는 법
var a = 10;
a = 100;

함수 내부에서 새로운 변수를 만들려면 무조건 var 키워드를 사용해야 한다.

var gv = "전역변수";

if(true) {
	 var lv = "지역변수????";

	 //console.log(gv); -> {}안쪽에서 출력결과 : 전역변수
	 //console.log(lv); -> {}안쪽에서 출력결과 : 지역변수????
}

console.log(gv);  -> {} 밖에서 출력결과 : 전역변수
console.log(lv);  -> {} 밖에서 출력결과 : 지역변수????

많이들 함수가 아니라 중괄호를 기준으로만 전역/지역이 분리되는게 아니냐고 오해한다.

{ } 밖에서 console.log(lv)로 출력해도 값이 뜬다. lv 자체가 중괄호 안의 변수에 접근할 수 있단 것이다. 즉, 중괄호 안에서 만든 var lv = "지역변수????";는 지역변수가 아니라 전역변수란 뜻이다. 전역과 지역을 구분짓는건 중괄호가 아니라 함수다!

전역 변수 간편 확인법
js 문법들은 전부 개발자 도구의 console탭 안에서 작성 가능하다.
js 파일에 변수나 함수를 만들어 저장하고 개발자도구에서 따로 호출하는 게 가능하다.
클라이언트 측 자바스크립트에서 브라우저를 제어할 때 쓰는 객체 중에 window가 있다. 개발자 도구 console 탭 안에서 window를 검색하면 브라우저와 관련된 다양한 property와 메서드를 확인할 수 있다. 굉장히 많으니까 필요할 때마다 검색해서 확인하자.
.
그런데 그 window 객체에 내가 만든 변수가 들어가 있다.
.
모든 전역 변수는 window라는 객체에 기본 property로 할당된다.

var gv = "전역변수";
var aaa = "aaa";

이렇게 만든 변수를 개발자도구에서 window객체로 찍어본다.
.

스코프
: 변수가 영향력을 발휘할 수 있는 범위 자체. 어떻게 보면 스코프가 전역/지역 변수를 구분짓는 역할

var gv = "전역변수";

function func() {
	console.log(gv);
}

func();

console.log(gv);

양쪽 모두 전역변수가 출력된다.

gv가 모든 영역에 영향력을 발휘할 수 있다. 이것을 전역 스코프라고 한다.

function func() {
  
	var lv = "지역변수";
	console.log(lv);
}  -> lv 변수가 영향력을 발휘하는 건 여기까지다. 함수 내부

func();

console.log(lv);

함수 안에서만 영향력을 발휘할 수 있는 범위를 지역 스코프라고 한다.

★ 함수는 서로의 스코프에 접근할 수 없다!
.
아주 중요한 개념이라 꼭 기억해야 한다.
아래는 예시

function a() {
	var apple = "사과";
}
function b() {
	a();
	console.log(apple);
}
b();
-
출력 결과
not defined 에러가 뜬다.

함수 안에서 다른 함수를 호출할 수도 있다.
여기서 b 함수 안에서 a함수를 호출했기 때문에 중괄호 안의 구문이 실행될텐데 그럼 함수 선언도 b안에서 되기 때문에 console.log(apple);하면 사과가 출력되지 않을까?라고 추측할 것이다. 그런데 정의되지 않았다는 에러가 뜬다.
.
함수 호출과는 전혀 상관없다. apple이 영향력을 발휘할 수 있는 범위는 애초에 함수가 만들어진 중괄호 안에서만이다.
.
함수 b에서 apple을 찾으면 안된다. b 안에 없기 때문이다. 그렇다고 전역변수 apple이 있는 것도 아니다. 그렇기 때문에 not defined 에러가 뜬다.
.
쉽게 말해 집 2개가 있는데 1번 집에 apple이 있다. 1번 집을 2번 집이 호출을 한다고 해서 1번 집에 있던 apple이 2번 집에 들어가는 게 아니다. 각각은 독립적인 구역이라서 호출 유무와 상관없이 집은 이미 함수를 만든 순간 결정되기 때문이다. 서로에게 영향력 발휘 불가능

스코프 체인
: 안쪽에서부터 외부를 탐색한다. 용어 이름보단 개념을 숙지하자.

var a = 10;    

function func1() {
	var b = 20;
	function func2() {
		var c = 30;
		console.log(a + b + c);
	}
  
	func2();
}

func1();

출력 결과
60
-> console.log(a + b + c) 부터 바깥쪽으로 탐색해나간다.

func2 함수에서 만들어둔 변수 3개에 모두 접근했기 대문에 func1을 호출했을 때 60이란 결과가 나온 것이다.

실행 과정은 이렇다.
먼저 func1을 호출해서 func1의 중괄호가 실행된다. 그리고 func2를 호출했다. 그래서 만들어둔 func2 함수가 실행되며 func2의 중괄호 안쪽이 실행되는 것이다. 그럴 때 console.log(a + b + c);를 실행하기 전에 a 변수는 func2에 존재하지 않는다. 그래서 안쪽에서 바깥쪽으로 탐색한다. func1을 봤는데 a가 없다. 그래서 최종적으로 전역 변수에 존재하는지 따진다. 전역 변수에 a가 존재하니까 그 값인 10을 할당시켜준다. b도 마찬가지로 func2에 없으니 안에서 바깥쪽으로 탐색해서 20을 할당. c는 func2에 존재하므로 30 할당.

변수 a는 전역 변수, 모든 영역에 영향력을 발휘할 수 있는 전역 스코프를 가짐.

파란색은 지역 스코프라 파란색 안에서만 논다. 파란색 안에 빨간색(func2)를 만들었다. 각 스코프들이 겹치게 된다. 이거 자체를 스코프 체인이라고 한다. 중첩 스코프, 스코프 버블 등으로도 불린다.

바깥에서 안쪽 탐색은 불가능

함수는 서로의 스코프에 접근할 수 없다!의 예시로 보았던 함수와 헷갈리면 안 된다.

function a() {
	var apple = "사과";
}
function b() {
	a();
	console.log(apple);
}
b();
-
출력 결과
not defined 에러가 뜬다.

→ a와 b 함수는 별개의 함수로 서로 독립적이다.

스코프 체인에서 본 예시는 함수 내부에 다른 함수가 들어간 경우다. 함수의 스코프들이 겹쳐져 있다.

렉시컬 스코핑(lexical scoping)
: 용어 이름보단 개념을 숙지하자.

var name = "younghee";

function func1() {
	console.log(name);
}

function func2() {
	name = "Jun"
	func1();
}

func2();

각각의 함수는 독립적이고 func2안에서 name에 Jun을 넣고 func1을 호출했다. func2를 호출한 결과는 어떻게 될까?

결과는 Jun이 출력된다.

맨 마지막에 func2를 호출했다. 그래서 func2를 먼저 봐야 한다. func2안의 name은 var 키워드를 사용하지 않았기 때문에 전역변수에 있는 name을 변경시킨다. 그런 후, func2에선 func1을 호출했기 때문에 func1로 가서 본다. console.log(name)라서 name을 출력하려고 하니 func1 안에 없기 때문에 전역변수에 name이 있는지 따진 거다. 보니까 func2를 호출했을 때 이미 Jun으로 바꿨기 때문에 Jun이 출력된다.

var 키워드를 사용한 경우

var name = "younghee";

function func1() {
	console.log(name);
}

function func2() {
	var name = "Jun"     <- var가 들어갈 경우
	func1();
}

func2();

func2에서 var name을 할 경우는 최종 결과에서 younghee가 출력된다.
func2에서 func1();을 호출한다고 해서 console.log(name);을 한 게 아니라고 배웠다.

과정을 설명해보자면 func2를 호출했다. func2로 가서 순차적으로 본다. var 키워드를 사용함으로써 func2 안에 있는 name이 영향력을 발휘할 수 있는 곳은 func2까지만이다. 그리고서 func1을 호출했다. console.log(name);을 하려는데 func1에 변수 name이 존재하지 않아서 함수 바깥쪽인 전역변수 영역에는 있나 따진 것이다. func1 밖엔 변수가 2개 있다. func2안의 지역변수 name과 전역변수 name이다. name이란 이름은 같지만 서로 다른 변수다.
결과적으로 전역변수의 값이 변경된 것이 아니기 때문에 younghee가 출력된다.

-> 전역 변수 / 지역 변수를 안다는 말은 스코프 내용을 이해하고 있단 말과 같다. 스코프로 인해서 전역/지역 변수를 구분지을 수 있기 때문이다.

어려운 내용

  1. 어렵다기보단 다시 깨달은 점. html에서 자바스크립트 파일을 연결할 때 이 코드를 쓴다.
<script src="js/main.js"></script>

script를 서브라임 텍스트에서 자동완성해주는 기능으로 태그를 썼는데 src가 아니라 type으로 자동완성해준 걸 몰랐다. 그래서 왜 연결이 안되는지 찾아봤더니 src가 없으니까 안 된 것이었다.

  1. 스코프 개념이 좀 뒤죽박죽 상태다. 이해했다고 생각하고 다음 개념을 듣고 있는데 앞의 개념이 잘못 잡혀서 다시 읽고 넘어가느라 바빴다.

해결 방법

  1. 태그를 정확히 쓰고 자동완성만 믿지 말자.
  2. 강의를 다시 듣고 정리한 개념도 복습해야겠다.

느낀 점

if문은 여러 조건으로 만들면 재밌는 결과가 나올 것 같아서 수업 들을 때부터 상상이 됐는데 스코프 개념은 어떤식으로 활용을 할지 상상이 안 된다. 얼른 개념을 익히고 실습으로 활용을 어떻게 하는지 보고 싶다.

0개의 댓글

관련 채용 정보