후기.
JS는 적당히 알기는정말 쉽다. 그러나 완전히 알기는 어렵다.
타입
값
네이티브
강제변환
문법
스코프
렉시컬 스코프
함수 vs 블록 스코프
호이스팅
스코프 클로저
JS는 적당히 알기는 정말 쉽다. 그러나 완전히 알기는 어렵다.
타입
값
네이티브
강제변환
문법
스코프
렉시컬 스코프
함수 vs 블록 스코프
호이스팅
스코프 클로저
값 VS 레퍼런스
"자바스크립트는포인터라는 개념 자체가 없고 참조하는 방법도 조금 다르다. 우선 어떤 변수가 다른 변수를 참조할 수 없다.
그냥 안된다.
더구나 자바스크립트에는 값 또는 레퍼런스의 할당 및 전달을 제어하는 구문 암시(Syntactic Hint)가 전혀 없다.
대신, 값의 타입만으로 값-복사, 레퍼런스-복사 둘 중 한쪽이 결정된다."
- 카일 심슨의 You don't know JS
네? 타입으로 결정한다?
강제변환
어떤 값을 다른타입의 값으로 바꾸는 과정이 명시적이면 '타입 캐스팅'
(값이 사용되는 규칙에 따라) 암시적이면 '강제변환(Coercion)이라고 한다.
또는
'타입 캐스팅'은 정적 타입언어에서 컴파일 시점에,
'강제변환'은 동적 타입 언어에서 런타임 시점에 발생한다.
그러나 자바스크립트에서는
대부분 모든 유형의 타입변환을 강제변환으로 뭉뚱그려 일컫는 경향이 있어서,
여기서는 '암시적 강제변환'과 '명시적 강제변환' 두 가지로 구별한다.
23.
강제변환
Ok. 명시적 형변환필요해!
'명시적:암시적 = 명백한 : 숨겨진 부수 효과'
그럼 왜 암시적인 형변환이 필요한 걸까?
자 더글라스 크락포드 는 자바스크립트 강제변환은 반드시 피해야 한다고 말한다. 그렇게 말하지만
다시 물어보자. 암시적 강제변환은 위험한 것일까?
암시적 강제변환의 목적은 중요한 내용으로부터
주의를 분산시켜 코드를 잡동사니로 가득 채워버리는
장황함(Verbosity), 보일러플레이트(Boilerplate), 불필요한 상세 구현을 줄이는 것
24.
강제변환
var a ='1' + 0;
var b = '1' - 0;
일반적으로 자바스크립트엔진에 맡겨 타입을 결정하는데,
+의 경우 문자열이
숫자보다 우선순위가 높고
+ 를 제외한 나머지 사칙연산자는 숫자가 문자열보다 우선순위가 높다.
25.
강제변환
느슨한/엄격한 동등 비교
느슨한동등 비교는 ==
엄격한 동등 비교는 ===
일반적으로 우리가 아는 이 둘의 차이점은 Value 비교는 물론,
Type 까지 Check해서 결과를 알려준다.
하지만.... 이곳에는 무서운 진실이 숨겨져 있다.
강제변환
느슨한/엄격한 동등 비교
비교과정에서 강제변환의 개입 여부가 들어있다.
ES5 11.9.3 추상적 동등 비교 알고리즘
모든 가능한 타입별 조합마다 (필요시) 강제변환을 수행한다.
var a = 42;
var b = "42";
a === b; //false
a == b; //true
이번에는 Boolean으로 비교한다면?
28.
강제변환
느슨한/엄격한 동등 비교
비교과정에서 강제변환의 개입 여부가 들어있다.
이번에는 Boolean으로 비교한다면?
var a = "42";
var b = true;
a == b ?
var a = "42";
var b = true;
a === b ?
29.
강제변환
느슨한/엄격한 동등 비교
비교과정에서 강제변환의 개입 여부가 들어있다.
if( a === null || a === undefined ) {
return ... }
if( a == null ){
return ... }
강제변환
이제 암시적 강제변환의결론을 내려보자.
- 피연산자 중 하나가 true/false 일 가능성이 있다면 '절대로' == 연산자를 쓰지 말자.
- 피연산자 중 하나가 [], " ", , 0이 될 가능성이 있으면 가급적 == 연산자를 쓰지 말자.
이런 상황이라면 == 대신 ===를 사용하여 여러분이 의도하지 않은 강제변환을 차단하는게 훨씬 좋다
문법
문의 완료 값
표현식의부수 효과
콘텍스트 규칙
연산자 우선순위
세미콜론 자동 삽입
문의 완료 값
표현식의 부수 효과
콘텍스트 규칙
연산자 우선순위
세미콜론 자동 삽입
34.
문법
문의 완료 값
"Theresult of evaluating a Statement is always a Completion value"
_ES5.1 12
var b;
if (true){
b = 4 + 38;
}
모든 문은 (그 값이 undefined라 해도) 완료 값을 가진다는 사실!!
var a, b;
a = if (true){
b = 4 + 38;
}
문법
표현식의 부수 효과
표현식의부수 효과
function foo() {
a = a + 1;
}
var a = 1;
foo();
var a = 42;
var b = a++;
var a = 42;
var b = ++a; // 42
var a = 42, b;
b = (a++, a);
a; b;
37.
문법
표현식의 부수 효과
표현식의부수 효과
function vowels(str){
var matches;
if (str) {
// 모든 모음을 추출한다.
matches = str.match( /[aeiou]/g);
if(matches){
return matches
}
}
}
vowels("Hello World");
function vowels(str){
var matches;
if (str && (matches = str.match(/[aeiou]/g))) {
return matches
}
}
vowels("Hello World");
38.
문법
연산자 우선 순위
vara = 42;
var b = "foo";
a && b; // "foo"
a || b' // 42
var a = 42;
var b = "foo";
var c = [1,2,3];
a && b || c; // ?
a || b && c; // ?
39.
문법
연산자 우선 순위
a|| b := a || b ? b : a
a && b := a && b ? a : b
단락 평가
function doSOmething(opts){
if (opts && opts.cool) {
// ...
}
}
40.
문법
세미콜론 자동 삽입(ASI)
세미콜론을써야한다는 주장
// 원래 코드
function getData() {
return
{
title: 'Maintainable Javascript',
author: 'Nicholas C. Zakas'
}
}
// 파서가 생각하는 코드
function getData() {
return;
{
title: 'Maintainable Javascript',
author: 'Nicholas C. Zakas'
};
}
이 예제에서 우리가 보기에 `getData()`는 데이터가 포함된 객체를 반환하는 함
수입니다. 하지만 ASI는 return 문 이후에 새로운 줄이 있으니 당연히 세미콜론
을 삽입합니다. 따라서 getDate( ) 함수는 undefined를 반환합니다.
41.
문법
세미콜론 자동 삽입(ASI)
세미콜론을써야한다는 주장
// 세미콜론은 빠졌지만 정상 동작합니다.
function getData() {
return {
title: 'Maintainable Javascript',
author: 'Nicholas C. Zakas'
}
}
42.
문법
세미콜론 자동 삽입(ASI)
세미콜론을쓰지 않아도 된다(쓰지 말아야 한다) 주장
function foo () {
return 42; // ok
}; // <– AVOID!
class Foo {
constructor () {
if (baz) {
return 42; // ok
}; // <– AVOID!
return 12; // ok
}; // <– AVOID!
}; // <– AVOID!
이 예제에서 우리가 보기에 `getData()`는 데이터가 포함된 객체를 반환하는 함
수입니다. 하지만 ASI는 return 문 이후에 새로운 줄이 있으니 당연히 세미콜론
을 삽입합니다. 따라서 getDate( ) 함수는 undefined를 반환합니다.