- 표현식이란?
- 문이 '실행'을 통해 어떤 동작을 수행하라는 지시라면; 표현식은 '평가'를 통해 값으로 반환해야 하는 문이며, 따라서 그 값을 변수나 배열의 요소, 객체의 프로퍼티에 할당할 수 있다!
- 스크립트가 실행되면 표현식(값 으로 나타낼 수 있는 것은 모두 표현식이다!)이 평가 되고(값 을 계산한다 - 다른 일은 하지 않는다!), 문이 수행 되는데(값 을 갖지 않지만, 주어진 표현식에 의거하여 상태를 바꾼다!), 그보다 앞서 let 및 const, function, class 등의 데이터 타입 선언이 이루어진다 ← 이 타입 선언은 데이터의 타입 을 알리고 이름 을 부여해서 나중에 참조 할 수 있도록 한다
-
표현식이란 어떤 값으로 평가되는 무엇 인데,
숫자(1)나 문자열 리터럴("안녕?"), 변수명(radius)도
(그에 할당된 값으로 평가되므로)표현식이다.
나아가, 연산자로 연결된
x+y또한 어떤 결과값을 나타내는 표현식이다. 스크립트 예약어인 true, false, null, undefined 및 this 역시 표현식이고, 배열의 요소에 접근하거나(ary[index]) 객체의 프로퍼터에 접근하는 것(obj.key), 함수 정의문(function() { .. }), 객체 생성자 함수(new Object();) 또한 표현식이다 -
1.
함수호출 표현식: Fnc
(args);먼저 Fnc(= 함수명)를, 이어서 args (= 인자)를 평가한 다음, Fnc 함수의 본체({ .. })를 실행하게 된다 ← 호출한 함수 내부에서 return 문을 반환한다면; 그 값이 함수 호출 표현식의 값 이 되고, 아니라면; undefined 값이 반환된다! -
2.
메서드호출 표현식: Obj.
sort();←sort();메서드에 접근하는 Obj(객체 또는 배열)는 해당 메서드 본체 안에서this키워드의 값이 되고, 자신을 호출한 객체에 작용하게 된다! -
3.
프로퍼티접근 표현식: 객체.
식별자에서 앞의 표현식이 먼저 평가되고, 이어서 . 뒤 식별자 를 찾고 그 값이 표현식의 전체 값 이 된다. 객체[프로퍼티키]및 배열[인덱스번호]접근에서는 내부 표현식을 평가하여 문자열로 변환하고, 그것이 전체 표현식의 값 으로 된다 ← 앞의 표현식이 null 이나 undefined 라면; 타입에러가 발생한다!
/* 변수의 선언 및 정의 ← 변수를 정의하면서 값을 할당해주면; 그 자체 문이다! */
const radius= 2 // const 변수 radius를 선언하면서 값 2를 할당한다
console.log(radius) // 2
/* 함수 이름(area)으로 (인수 radius의 값 2를 전달하면서)area 함수를 호출한다 */
area(radius); // 12.566370614359172
/* 함수의 선언 및 정의 ← 함수는 '호이스팅'된다! */
function area(radius) { /* 함수 객체({ .. })를 생성하여 이름(area)을 붙여준다 ← 전달된 인수가 있으면; 매개변수(radius)로 받는다 */
// 전달받은 매개변수(radius)를 써서 작업을 수행하고(Math.PI * radius * radius),
return Math.PI * radius * radius // 그 결과물을 호출자에게 돌려준다(retrun 문)
}
☞ 함수는 선언하는 즉시 맨 위로 끌어올려지고('호이스팅'), 그리하여 함수가 정의되기 이전이라도 그 이름으로 함수를 호출할 수 있다!
- 문이란?
- 표현식은 '평가'를 통해 값 으로 바뀌고, 문은 '실행'을 통해 어떤 동작 을 수행하는데, '부수 효과'가 있는 표현식을 평가하는 것(= 표현문)은 그 자체로 문이 될 수 있다. 나아가, 변수를 선언하거나 함수를 정의하는 것 또한 일종의 문이라고 할 수 있다
- 1. 스크립트에서 가장 기본이 되는 문은 조건문인데, if 문은 조건 을 평가하여 trusy한 값 이라면; 작업을 수행하고, falsy한 값 이라면; (아무 일도 하지 않고, 그냥 나가서)아래 코드로 내려간다
- 2. if .. else 문은 조건 을 평가하여 각각의 방향으로 분기한다
- 3. if 문을 중첩할 수도 있고, if .. elseif .. else 문은 순차적으로 조건 을 평가하면서 내려간다
- 4. if .. elseif .. else 문이 순차적으로 조건 을 평가하면서 내려가는 반면, switch .. case 문은 조건 을 평가하여 맞는 case 로 분기한다
- 5. for 루프문은 스크립트에서 가장 많이 사용되는 중요한 문인데, 카운터 변수 초기값 을 시작점으로 하여 조건 을 평가하여 블록 안으로 들어가 작업을 수행하고, 증감식 으로 초기값을 증감시키면서 (조건에 부합하는 한도 내에서)반복 작업을 수행해나간다
if(조건) 코드;
☞ 조건 을 '평가'한 '값'이 참이라면; 코드 를 수행하고, 아니라면; 그냥 건너뛰어 아래로 내려간다
if(조건) 코드1; // 조건에 맞으면; 코드1을 수행한다
else 코드2; // 아니라면; 코드2를 수행한다
☞
위 if .. else 문은 삼항 조건 연산자를 써서 보다 간결하게 작성할 수 있다:
조건 ? 코드1 : 코드2;
←
조건 이 'trusy한 값'이면; 코드1, 'falsy한 값'이면; 코드2 를 수행한다
if(조건) { // 조건이 참이면; 코드1을 수행한다
코드1;
} else { // 아니라면; 여기로 온다
if(조건2) 코드 2; // 조건2가 참이면; 코드2를 수행한다
else 코드3; // 아니라면; 여기로 온다
}
if(조건) 코드1; // 조건이 참이면; 코드1을 수행한다
else if (조건2) 코드2; // 아니라면; 여기로 온다
else if (조건3) 코드3; // 역시 아니라면; 여기로 온다
else 그외; // 위 모든 조건을 만족하지 못하는 경우; 여기로 온다!
☞ 참고로, if 등의 조건문을 쓰는 대신, 조건 연산자 ?나 논리 연산자 || 및 &&를 적절히 활용하면; 보다 간결한 코드를 작성할 수 있다!
switch(조건) { // 조건값(=== 비교)에 따라 맞는 case로 분기한다..
case 1: 실행문; // break가 없으므로, 계속 다음 케이스를 수행한다..
case 2: 실행문; // 조건에 맞는 case라면; 작업을 수행하고,
break; // 작업 수행 후에는 switch문을 빠져나간다!
case 3: 실행문;
return "리턴"; // 실행문 안에 return문이 들어 있다면; break는 생략할 수 있다!
default: 실행문; // 조건에 일치하는 case 값이 하나도 없을 때 여기로 온다
}
☞
switch 문의 case 값에 표현식을 사용하는 것도 가능하지만,
숫자나 문자열 리터럴을 쓰는 것이 안전하고 알기 쉽다!
const ary= [1, 2, 3] // 배열 변수 ary 선언 및 정의
// for 루프문으로 배열 ary의 각 요소 값을 0으로 바꾼다
for(let i=0; i < ary.length; ary[i++]=0) { // 카운터 변수 선언 및 초기화; 조건 평가; 증감 카운터
; // 빈 문 ← for 루프에서 이 ;만으로도 필요한 일을 수행할 수 있다!
}
console.log(ary) // [0, 0, 0] ← for 문의 증감식(ary[i++]=0)에 의해 배열의 각 요소값으로 들어갔다!
* cf) 부수 효과가 있는 표현식과 대입 할당문(및 증가/감소 연산자가 붙은 변수), 객체의 프로퍼티를 삭제하는 delete 연산자, 함수호출 또한 '부수 효과'가 있어 사실상의 '문'으로 볼 수 있다!