You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
````warn header="Declaring twice triggers an error"
138
+
A variable should be declared only once.
139
+
140
+
A repeated declaration of the same variable is an error:
141
+
142
+
```js run
143
+
let message = "This";
144
+
145
+
// repeated 'let' leads to an error
146
+
let message = "That"; // SyntaxError: 'message' has already been declared
147
+
```
148
+
So, we should declare a variable once and then refer to it without `let`.
149
+
````
150
+
138
151
```smart header="함수형 언어"
139
152
[함수형(functional)](https://en.wikipedia.org/wiki/Functional_programming) 프로그래밍 언어는 변숫값 변경을 금지합니다. [스칼라(Scala)](http://www.scala-lang.org/)와 [얼랭(Erlang)](http://www.erlang.org/)은 대표적인 함수형 언어입니다.
위와 같은 에지 케이스를 왜 살펴보았을까요? 이런 예외적인 경우를 꼭 기억해 놓고 있어야만 할까요? 그렇지는 않습니다. 개발을 하다 보면 자연스레 이런 경우를 만나고 점차 익숙해지기 때문에 지금 당장 암기해야 할 필요는 없습니다. 하지만 아래와 같은 방법을 사용해 이런 예외 상황을 미리 예방할 수 있다는 점은 알아두시길 바랍니다.
200
204
201
-
일치 연산자 `===`를 제외한 비교 연산자의 피연산자에 `undefined`나 `null`이 오지 않도록 특별히 주의하시기 바랍니다.
202
-
203
-
또한, `undefined`나 `null`이 될 가능성이 있는 변수가 `>= > < <=`의 피연산자가 되지 않도록 주의하시기 바랍니다. 명확한 의도를 갖고 있지 않은 이상 말이죠. 만약 변수가 `undefined`나 `null`이 될 가능성이 있다고 판단되면, 이를 따로 처리하는 코드를 추가하시기 바랍니다.
205
+
- 일치 연산자 `===`를 제외한 비교 연산자의 피연산자에 `undefined`나 `null`이 오지 않도록 특별히 주의하시기 바랍니다.
206
+
- 또한, `undefined`나 `null`이 될 가능성이 있는 변수가 `>= > < <=`의 피연산자가 되지 않도록 주의하시기 바랍니다. 명확한 의도를 갖고 있지 않은 이상 말이죠. 만약 변수가 `undefined`나 `null`이 될 가능성이 있다고 판단되면, 이를 따로 처리하는 코드를 추가하시기 바랍니다.
null 병합 연산자는 OR 연산자 `||`와 상당히 유사해 보입니다. 실제로 위 예시에서 `??`를 `||`로 바꿔도 그 결과는 동일하기까지 하죠.
38
+
null 병합 연산자는 OR 연산자 `||`와 상당히 유사해 보입니다. 실제로 위 예시에서 `??`를 `||`로 바꿔도 그 결과는 동일하기까지 하죠. [이전 챕터](info:logical-operators#or-finds-the-first-truthy-value)에서 관련 내용을 살펴본 바 있습니다.
35
39
36
40
그런데 두 연산자 사이에는 중요한 차이점이 있습니다.
37
41
- `||`는 첫 번째 *truthy* 값을 반환합니다.
38
-
- `??`는 *값이 정의되어있는* 첫 번째 값을 반환합니다.
42
+
- `??`는 첫 번째 *정의된(defined)* 값을 반환합니다.
39
43
40
44
`null`과 `undefined`, 숫자 `0`을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 합니다.
41
45
42
-
예시:
46
+
예시를 살펴봅시다.
43
47
44
48
```js
45
49
height = height ??100;
46
50
```
47
51
48
-
`height`에 값을 정의하지 않은 상태라면 `height`엔 `100`이 할당됩니다. 그런데 `height`에 `0`이 할당된 상태라면 값이 바뀌지 않고 그대로 남아있습니다.
52
+
`height`에 값이 정의되지 않았다면 `height`엔 `100`이 할당됩니다.
49
53
50
54
이제 `??`와 `||`을 비교해봅시다.
51
55
@@ -56,17 +60,19 @@ alert(height || 100); // 100
56
60
alert(height ??100); // 0
57
61
```
58
62
59
-
`height ||100`은 `height`에 `0`을 할당했지만 `0`을 falsy 한 값으로 취급했기 때문에 `null`이나 `undefined`를 할당한 것과 동일하게 처리합니다. 높이에 `0`을 할당하는 것과 유사한 유스케이스에선 이처럼 `||`는 부정확한 결과를 일으킬 수 있습니다.
63
+
`height ||100`은 `height`에 `0`을 할당했지만 `0`을 falsy 한 값으로 취급했기 때문에 `null`이나 `undefined`를 할당한 것과 동일하게 처리합니다. 따라서 `height ||100`의 평가 결과는 `100`입니다.
64
+
65
+
반면 `height ??100`의 평가 결과는 `height`가 정확하게 `null`이나 `undefined`일 경우에만 `100`이 됩니다. 예시에선 `height`에 `0`이라는 값을 할당했기 때문에 얼럿창엔 `0`이 출력됩니다.
60
66
61
-
대신 `height ??100`은 `height`가 정확히 `null`이나 `undefined`일때만 `height`에 `100`을 할당합니다.
67
+
이런 특징 때문에 높이처럼 `0`이 할당될 수 있는 변수를 사용해 기능을 개발할 땐 `||`보다 `??`가 적합합니다.
62
68
63
69
## 연산자 우선순위
64
70
65
-
[`??`의 연산자 우선순위](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)는 `7`로 꽤 낮습니다.
71
+
[`??`의 연산자 우선순위](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)는 `5`로 꽤 낮습니다.
66
72
67
-
대부분의 연산자보다 우선순위가 낮고, `=`와 `?` 보다는 조금 높죠.
73
+
따라서 `??`는 `=`와 `?` 보다는 먼저, 대부분의 연산자보다는 나중에 평가됩니다.
68
74
69
-
따라서 복잡한 표현식 안에서 `??`를 사용할 땐 괄호를 추가해주는 게 좋습니다.
75
+
그렇기 때문에 복잡한 표현식 안에서 `??`를 사용해 값을 하나 선택할 땐 괄호를 추가하는 게 좋습니다.
70
76
71
77
```js run
72
78
let height =null;
@@ -78,27 +84,34 @@ let area = (height ?? 100) * (width ?? 50);
78
84
alert(area); // 5000
79
85
```
80
86
81
-
`*`가 `??`보다 우선순위가 높기 때문에 괄호를 생략하게 되면 `*`가 먼저 실행되어 아래 코드처럼 동작할 겁니다.
87
+
그렇지 않으면 `*`가 `??`보다 우선순위가 높기 때문에 `*`가 먼저 실행됩니다.
88
+
89
+
결국엔 아래 예시처럼 동작하겠죠.
82
90
83
91
```js
84
92
// 원치 않는 결과
85
93
let area = height ?? (100* width) ??50;
86
94
```
87
95
88
-
`??`엔 자바스크립트 언어에서 규정한 또 다른 제약사항이 있습니다. 안정성 관련 이슈 때문에 `??`는 `&&`나 `||`와 함께 사용하는 것이 금지되어 있습니다.
96
+
`??`엔 자바스크립트 언어에서 규정한 또 다른 제약사항이 있습니다.
89
97
90
-
아래 예시를 실행해봅시다. 문법 에러가 발생합니다.
98
+
**안정성 관련 이슈 때문에 `??`는 `&&`나 `||`와 함께 사용하지 못합니다.**
99
+
100
+
아래 예시를 실행하면 문법 에러가 발생합니다.
91
101
92
102
```js run
93
103
let x =1&&2??3; // SyntaxError: Unexpected token '??'
94
104
```
95
105
96
-
이 제약에 대해선 아직 논쟁이 많긴 하지만 어쨌든 이슈가 있어서 명세서에 제약이 추가된 상황입니다.
106
+
이 제약에 대해선 아직 논쟁이 많긴 하지만 사람들이 `||`를 `??`로 바꾸기 시작하면서 만드는 실수를 방지하고자 명세서에 제약이 추가된 상황입니다.
0 commit comments