이 시리즈는 You Don't Know JS Yet (1판인 You Don't Know JS의 개정판) 을 가지고 스터디를 진행하면서 요약 정리한 글입니다. 내용에 대한 퀴즈도 깃헙 리포지토리에 올리고 있으니 참고하시면 더 도움이 되실 것 같습니다. 내용에 대해 오류가 있거나 궁금하신 점이 있다면 댓글 달아주세요!
이후 YDKJSY 책 시리즈들을 통해서 JS의 주요 뼈대 개념들을 깊게 다뤄볼 것입니다. 이에 대해 간략하게 알아보는 내용이 이번 챕터입니다.
대부분의 언어에서는 'Lexically Scoped' 라고 불리는 성질을 가지면서 변수가 작동됩니다. 코드를 작성하는 개발자의 입장에서 결정이 되고, 프로그램은 개발자가 작성한 코드를 따라 작동되죠. 하지만 JS는 이 성질을 가지면서 다른 언어에는 없는 특수한 성질 두가지를 가집니다. 바로 hoisting과 function-scoped var입니다. 이런 성질 때문에 JS에서 Closure는 프로그램 작동에 중요한 역활을 합니다. 이에 대해선 바로 다음 책인 Scope & Closure에서 다룰 예정입니다.
이전 챕터에서 다룬 Prototypes도 꽤나 중요한 뼈대가 됩니다. 왜냐하면 JS는 OOP가 아니고 다 패러다임 언어이기 때문에 객체지향적 접근 없이 객체들간의 관계를 Prototype을 통해 연결할 수 있기 때문입니다. 이렇게 객체를 연결하는 것을 behavior delegation이라고 합니다. 이에 대해선 세번째 책인 Objects & Classes에서 다룰 예정입니다.
JS 개발자들이 가장 무시하고 있는 것이 바로 JS에서의 타입입니다. (저도 마찬가지고) JS 자체적으론 타입에 대해서 완벽하지 않고, 타입을 통한 개발을 할 땐 다른 애드온들(대표적으로 Typescript)을 사용하게 되는 경우가 많습니다. 다만 JS에서도 충분히 타입에 대한 접근이 가능하고 이를 활용할 수 있다고 합니다. 이에 대해선 네번째 책인 Types & Grammar에서 다룰 예정입니다.
이후 내용은 책 후반에 있는 Appendix에 있는 내용을 정리한 부분입니다. 사소한 개념들을 간단하게 정리해봅시다.
var myName = "Sungwoo";
var yourname = myName;
myName = "Park"
console.log(yourname); // "Sungwoo"
var myName = {
first: "Sungwoo",
last: "Park"
};
var yourName = myName;
myName.last = "Kim";
console.log(yourName.last); // "Kim"
다른 언어들과는 다르게 JS는 변수에 value가 들어가는지 reference가 들어가는지는 그 값의 특성에 맞게 들어가게 됩니다. 대표적으로 대부분의 Primitive values는 value로 들어가게 되고, object는 reference로 들어가게 됩니다.
var wellKnownFunciton = function secret(somethings) {
// ..
return somethings;
};
var secretFunction = function (somethings) {
// ..
return somethings;
};
console.log(wellKnownFunction.name); // "secret"
console.log(secretFunction.name); // "secretFunction"
secretFunction
과 같이 함수표현식에 함수 이름을 주지 않은 상태로 함수를 부여했는데, 이러한 함수를 anonymous fucntion expression 이라고 합니다. 반대로 wellKnownFunction
과 같이 함수표현식에 이름을 부여한 함수를 넣는 것을 named function expression이라고 합니다.
아무리 익명 함수에 name 프로퍼티가 있다고 해도, 익명 함수들은 서로 구분할 수 없습니다. name 프로퍼티는 identifier가 아니기 때문에 (그리고 위에서 본 것과 같이 익명 함수의 name 프로퍼티는 실제 변수의 name이기도 해서) 구분할 수 없습니다.
그 외에도 generator, async, arrow function등 다양한 함수 표현이 있습니다.
const testComparison = (x) => {
if (x) {
console.log("IF RUNS!");
}
while (x == true) {
console.log("WHILE RUNS ONCE!");
x = false;
}
}
testComparison(1); // if and while work!
testComparison("hello"): // if works, but while doesn't work :(
프로그램 분기를 나누기 위해 조건문, 반복문을 사용하면서 비교연산자를 사용하는데 JS의 특징인 Coercive conditional comparison 덕분에 주의가 필요합니다. 대표적으로 위와 같이 if와 while 둘 다 작동되게 만들고 싶었던 코드도, 예상했던 것과는 다르게 작동할 수 있습니다. 저 코드에서 while의 조건문을 Boolean(x) == true
로 바꾼다면 더욱 의도적으로 코드를 작성할 수 있을 것입니다.
function Classroom() {
// Some functions
}
Classroom.prototype.welcome = function hello() {
console.log("Welcome, students!");
};
var mathClass = new Classroom();
mathClass.welcome(); // Welcome, students!
ES6 이전에는 위 코드와 같이 함수와 프로토타입을 이용해 클래스와 비슷하게 객체를 만들수 있었습니다. 위 코드에 작성된 Classroom.prototype
은 Classroom의 프로토타입을 말하는 것이 아니라, Classroom을 통해 만들어진 하위 객체에 대해 설정하는 것입니다. 그렇다면 위와 같이 만들어진 mathClass
는 prototype을 통해 설정된 함수를 가지고 있는 것입니다.