-
Notifications
You must be signed in to change notification settings - Fork 13
javascript in depth all you need to know about expressions statements and expression statements
원문: All you need to know about Javascript's Expressions, Statements and Expression Statements
이 포스팅을 다보고 나면 아래 코드가 작동하는 방식과 작동 원리에 대해 자세히 설명 할 수 있어야한다.
{} + 1 // 1
{2} + 2 // 2
{2+2} + 3 // 3
{2+2} - 3 // -3
Javascript에는 크게 두 가지 문법 카테고리가 있다.
- Statements (구문)
- Expressions (표현식)
표현식은 구문처럼 동작 할 수 있기에 구별 하는 것은 중요하다. 표현식 구문도 존재한다. 반면에 구문은 표현식 처럼 동작할 수 없다.
표현식은 단일 값이 되는 자바스크립트 코드 스니펫이다. 표현식은 원하는 만큼 길 수 있지만, 항상 단일 값이된다.
2 + 2 * 3 / 2
(Math.random() * (100 - 20)) + 20
functionCall()
window.history ? useHistory() : noHistoryFallback()
1+1, 2+2, 3+3
declaredVariable
true && functionCall()
true && declaredVariable
위의 모든 표현식은 단일 값을 반환한다. 따라서 아래의 console.log
인자는 단일 값을 반환하게 되고 화면에 출력된다.
console.log(true && 2 * 9) // 18
예를 들어,
const assignedVariable = 2; //this is a statement, assignedVariable is state
assignedVariable + 4 // expression
assignedVariable * 10 // expression
assignedVariable - 10 // expression
console.log(assignedVariable) // 2
위의 예제에 있는 모든 표현식에도 불구하고 assignedVariable
의 값은 여전히 2이다. 표현식이 무조건 상태(변수)를 변경하는 것이 아닌 것이다.
하지만 함수는 다르다. 함수 호출은 표현식이지만, 함수는 상태를 변경하는 구문을 포함 할 수 있다.
foo () => {
// ...
}
위의 예제에선 foo()
함수는 원하는 내용을 채운다면 값을 반환하거나 변수 값을 변경할 수 있다. 그러나 아래와 같이 작성된다면 어떨까?
const foo = foo () => {
assignedVariable = 14
}
여전히 foo()
함수는 표현식이지만, 호출을 한다면 상태 변경이 가능하다. 즉 표현식과 구문의 경계가 모호하다. foo()
함수를 더 나은 방식으로 바꾸어 보자.
const foo = foo () => {
return 14 //explicit return for readability
}
assignedVariable = foo()
추가로 더 나은 방법은 아래와 같다.
const foo = foo (n) => {
return n//explicit return for readability
}
assignedVariable = foo(14)
이렇게하면 코드가 더 읽기 쉽고 호환되며, 표현식과 구문 사이에 명확한 구별과 분리가 있다. 이것은 기능적이고 선언적인 자바스크립트의 기본이다.
구문은 함수형 프로그래밍의 골칫거리이다. 기본적으로 구문은 행동을 수행하는 역할을 가진다.
자바스크립트에선 값이 기대되는 곳에서는 구문을 사용할 수 없다. 함수의 인수, 할당의 오른쪽(right-side), 피연산자, 반환 값 등으로 사용할 수 없다.
foo(if () {return 2}) //js engine mind = blown
자바스크립트에서의 구문은 아래의 형태로 존재한다.
- if
- if-else
- while
- do-while
- for
- switch
- for-in
- with (deprecated)
- debugger
- variable declaration
브라우저의 콘솔에 아래의 스니펫을 입력하고 엔터를 눌러보자.
if (true) {9+9}
이 스니펫이 18
을 반환하는 결과를 볼 것이다. 그럼에도 불구하고 표현식으로 사용할 수 없으며, 값을 기대하는 곳에서 사용할 수 없다. 구문이 아무것도 반환을 하지 않는다고 예상하기 때문에 이상하다. 반환 값은 사용할 수 없다면 거의 쓸모가 없다. 이상하다.
함수 선언은 구문이다.
function foo (func) {
return func.name
}
함수 표현식은 표현식이다. 아래는 익명 함수라고 불리는 함수다.
console.log(foo(function () {} )) // ""
이름이 있는 함수 표현식은 익명 함수와 같은 표현식이지만 이름이 잇다는 차이 점이 있다.
console.log(foo(function myName () {} )) // "myName"
표현식으로서의 함수와 선언문으로서의 함수 사이의 구별을 할 줄 알면 아래의 내용도 이해할 수 있을 것이다.
자바스크립트가 값을 기대하는 함수를 선언할 때마다 값을 값으로 사용할 수 없다면, 오류가 발생하게 된다. 블록 구문 (즉, 값을 기대하지 않는 경우)의 스크립트, 모듈 또는 최상위 레벨의 글로벌 수준에서 함수를 선언하면 함수 선언이 발생한다.
예를 들어
if () {
function foo () {} // top level of block, declaration
}
function foo () {} //global level, declaration
function foo () {
function bar() {} //top level of block, declaration
}
function foo () {
return function bar () {} // named function expression
}
foo(function () {}) // anonymous function expression
function foo () {
return function bar () {
function baz () {} // top level of block, declaration
}
}
function () {} // SyntaxError: function statement requires a name
if (true){
function () {} //SyntaxError: function statement requires a name
}
이것은 매우 간단하다.
2+2; //expression statement
foo(); //expression statement
표현식을 표현식 구문으로 변환할 수 있다. 단지 라인 끝에 세미콜론을 추가하거나 작업을 수행할 수 있는 자동 세미콜론 삽입을 허용하면 된다. 2+2
자체는 표현식이지만 완전한 라인은 문장이다.
2+2 // on its own is an opposition
foo(2+2) //so you can use it anywhere a value is expected
true ? 2+2 : 1 + 1
function foo () {return 2+2}
2+2; //expression statement
foo(2+2;) //syntaxError
세미콜론으로 여러 구문을 같은 줄에 유지할 수 있다.
const a; function foo () {}; const b = 2
쉼표 연산자는 다중 표현식을 연결하고, 마지막 표현식식 반환할 수 있도록 한다.
console.log( (1+2,3,4) ) //4
console.log( (2, 9/3, function () {}) ) // function (){}
console.log( (3, true ? 2+2 : 1+1) ) // 4
Javascript 엔진에 값을 기대하는 한 가지 방법은 괄호없이 ()를 사용하는 것이다. 각 표현식은 console.log의 인수로 처리된다.
function foo () {return 1, 2, 3, 4}
foo() //4
모든 표현식은 왼쪽에서 오른쪽으로 계산되고 마지막 표현식이 반환된다.
익명함수는 표현식이 될 수 있다 자바스크립트가 값을 기대하는 곳에서 익명함수를 사용한다면, 괄호로 값을 기대 하도록 자바스크립트에 지시할 수 있다면, 익명함수를 해당 값으로 전달할 수 있다는 것을 의미한다.
function () {}
그래서 위의 예제는 유효하지 않지만 아래의 예제는 유효하다.
(function () {}) // this returns function () {}
익명의 함수를 괄호 안에 넣으면 익명의 함수가 즉시 실행되어 반환된다. 즉, 다음과 같이 즉시 호출할 수 있다.
(function () {
//do something
})()
그래서 아래 예제들은 가능하다.
(function () {
console.log("immediately invoke anonymous function call")
})() // "immediately invoke anonymous function call"
(function () {
return 3
})() // 3
console.log((function () {
return 3
})()) // 3
//you can also pass an argument to it
(function (a) {
return a
})("I'm an argument") // I'm an argument
r: 2+2 // valid
foo()
const foo = () => {}
위의 내용은 글로벌 스코프에있는 일련의 구문으로, 유효한 구문으로 분석되어 실행된다 .r
은 레이블이라고 부르며 루프를 깨는 데 주로 유용합니다. 예:
loop: {
for (const i = 0; i < 2; i++) {
for (const n = 0; n <2; n++) {
break loop //breaks outer loop and stops entire loop
}
}
}
표현식이나 표현식 구문에 레이블을 미리 설정할 수 있다. 이렇게함으로써 가변 실험실을 만들지 않는다는 점에 유의하라.
lab: function a () {}
console.log(lab) //ReferenceError: lab is not defined
중괄호 { }
를 사용하면, 아래와 같이 표현식 구문과 명령문을 그룹화할 수 있다.
{var a = "b"; func(); 2+2} // 4
위의 내용을 브라우저 콘솔에 붙여 넣으면 4를 반환하고 console.log (a)
를 수행하면 문자열 b
를 얻는다. 익숙한 객체 리터럴과는 다른 블록 구문 호출 할 수 있다.
console.log({a: 'b'}) // {a: 'b'}
console.log({var a = "b", func(), 2+2}) // SyntaxError
const obj = {var a = "b", func(), 2+2} // SyntaxError
블록 문을 값 또는 표현식으로 사용할 수 없다. console.log는 함수이므로 인수로 구문을 사용할 수 없다. 그러나 객체는 리터럴은 허용한다.
{} + 1 //1
{2} + 2 // 2
{2+2} + 3 // 3
{2+2} -3 // -3
구문 오류를 발생시키거나 각각 1, 4, 7을 반환할 것으로 예상할 수 있다. 구문은 값으로 사용될 수 없기 때문에 어떤 것도 반환해서는 안 된다는 것을 명심하라. 따라서 Javascript는 오류를 던지기보다는 +
연산자의 피연산자를 숫자 또는 문자열로 변환하려고 시도한다. 따라서 블록 문에 의해 반환되는 것은 피연산자로 사용되는 0
으로 암묵적으로 강요된다.
일부 의역이 들어간 경우도 있으므로 해당 원문의 내용과 조금 다를 수 있습니다.
문제가 될 소지가 있다거나 혹은 수정이 필요한 사항이 있다면 있다면 issues 보내주세요.
기술문서
- 호출스택
- 원시자료형
- 값타입과 참조타입
- 명시적 변환, 암시적 변환, Nominal, 구조화, 덕 타이핑
- == vs === vs typeof
- 함수 범위, 블록 범위, 렉시컬(lexical) 범위
- 식(expression) vs 문(statement)
- IIFF, Modules, Namespaces
- 메세지큐와 이벤트루프
- setTimeout, setInterval, requestAnimationFrame
- 자바스크립트 엔진
- 비트 연산자, 형식화 배열, 버퍼(배열)
- DOM과 Layout Trees
- 팩토리와 클래스
- this, call, apply, bind
- new, 생성자, instanceof, 인스턴스
- 프로토타입의 상속과 체인
- Object.create와 Object.assign
- map, reduce, filter
- 순수함수, 부수효과, 상태변이
- Closure
- 고차함수
- 재귀
- 컬렉션과 생성기
- Promise
- async, await
- 자료구조
- 함수 성능과 빅 오 표기법
- 알고리즘
- 상속, 다형성, 코드의 재사용성
- 설계패턴
- 부분 어플리케이션, 커링, Compose, Pipe
- 클린코드