개발자가 의도적으로 값의 타입을 변환하는 것
개발자의 의도와는 상관없이 표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되는 것
표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가과정을 생략하는 것
// 논리곱
'Cat' && 'Dog' // 'Dog'
// 논리합
'Cat' || 'Dog' // 'Cat'
// 논리합(||) 연산자
true || anything // true
false || anything // anything
// 논리곱(&&) 연산자
true && anything // anything
false && anything // false
좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티를 참조를 참조한다.
var str = '';
var length = str?.length;
console.log(length); // 0
좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다.
변수에 기본값을 설정할 때 유용하다.
// 0이나 ''도 기본값으로 유효하다면 유용하다.
var foo = null ?? 'default string';
console.log(foo); // 'default string'
var foo = '' ?? 'default string';
console.log(foo); // ''
프로퍼티 값이 함수일 경우 일반함수와 구분하기 위해 메서드(method)라 부른다.
클래스에 의해 생성되어 메모리에 저장된 실체를 말한다.
원시 타입의 값, 즉 원시값은 변경 불가능한 값(immutable value)
이다.
원시값을 변수에 할당하면 변수에는 실제값이 저장
된다.
원시값을 갖는 변수를 다른 변수에 할당하면 원본의 원시값이 복사되어 전달된다. 이를 값에 의한 전달(pass by value)
이라 한다.
객체는 변경 가능한 값(mutable value)
이다.
객체를 변수에 할당하면 변수에는 참조값이 저장
된다.
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달된다. 이를 참조에 의한 전달(pass by reference)
이라 한다.
객체는 원시값처럼 크기가 일정하지 않아서, 복사해서 생성하는 비용이 많이든다. 즉, 메모리를 효율적으로 사용하기 어렵다.
따라서 객체는 객체를 복사해 생성하는 비용을 절약하기 위해서 변경 가능한 값으로 설계되었고, 이로인해 여러 개의 식별자가 하나의 객체를 공유한다는 구조적인 단점을 안고있다.
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달되는데, 이때 두 객체는 저장된 메모리 주소는 다르지만 동일한 참조값을 갖는다. 즉, 두 객체는 동일한 객체를 가리킨다. 따라서 원본 또는 사본 중 어느 한쪽에서 객체의 프로퍼티 값을 변경하거나 삭제하면 서로 영향을 주고 받는다.
객체를 불변 객체로 만들어 사용한다.
객체의 복사본을 새롭게 생성하는 비용은 들지만, 객체를 마치 원시값처럼 변경 불가능한 값으로 동작하게 만드는 것이다. 객체의 상태 변경이 필요한 경우에는 객체를 깊은 복사(Deep copy)를 통해 새로운 객체를 생성하고 재할당을 통해 교체한다.
이를 통해 외부 상태가 변경되는 부수 효과를 없앨 수 있다.
재할당이 금지된 변수
마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체
를 말한다. length 프로퍼티를 갖기 때문에 유사배열객체이고, for 문으로 순회할 수도 있다.
자바스크립트의 문자열은 유사배열객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.
자바, C++같은 클래스 기반 객체지향 프로그래밍 언어는 사전에 정의된 클래스를 기반으로 객체(인스턴스)를 생성한다. 즉, 객체를 생성하기 이전에 이미 프로퍼티와 메서드가 정해져 있으며 그대로 객체를 생성한다. 객체가 생성된 이후에는 프로퍼티를 삭제하거나 추가할 수 없다.
자바스크립트는 클래스 없이 객체를 생성할 수 있으며, 객체가 생성된 이후라도 동적으로 프로퍼티와 메서드를 추가할 수 있다. 이는 사용하기 편리하지만 성능 면에서 이론적으로 클래스 기반 객체지향 프로그래밍 언어의 객체보다 생성과 프로퍼티 접근에 비용이 더 많이 드는 비효율적인 방식이다.
따라서 V8 자바스크립트 엔진에서는 프로퍼티에 접근하기 위해
동적 탐색(dynamic lookup) 대신 히든 클래스(hidden class)라는 방식을 사용해 C++ 객체의 프로퍼티에 접근하는 정도의 성능을 보장
한다.
객체를 프로퍼티 값으로 갖는 객체의 경우 얕은 복사는 한 단계까지만 복사하는 것을 말하고, 깊은 복사는 중첩되어 있는 객체까지 모두 복사하는 것을 말한다.
함수는 필요할 때 여러 번 호출할 수 있다. 함수는 몇 번이든 호출할 수 있으므로 코드의 재사용이라는 측면에서 매우 유용
하다.
일반객체는 호출할 수 없지만, 함수는 호출할 수 있다.
값의 성질을 갖는 객체를 일급 객체라한다.
자바스크립트 함수는 일급 객체이다. 함수가 일급 객체라는 것은 함수를 값처럼 자유롭게 사용할 수 있다는 의미이다.
생성자 함수(constructor function)
생성자 함수는 객체를 생성하는 함수를 말한다.
화살표 함수는 생성자 함수로 사용할 수 없으며 기존의 함수와 this 바인딩 방식이 다르고, prototype 프로퍼티가 없으며 arguments 객체를 생성하지 않는다.
재귀 함수는 자기 자신을 호출하는 행위를 말한다. 재귀 함수는 탈출 조건이 없으면 함수가 무한 호출되어 스택 오버플로(stack overflow) 에러가 발생한다.
함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수
매개변수를 통해 함수의 외부에서 콜백함수를 전달받은 함수
부수 효과가 없는 함수
, 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수이다.
즉, 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 반환값을 만든다.
순수함수의 또 하나의 특징은 함수의 외부 상태를 변경하지 않는다는 것이다. 즉, 순수 함수는 어떤 외부 상태에도 의존하지 않으며 외부 상태를 변경하지도 않는 함수이다.
var count = 0;
// 순수 함수 increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환
function increase(n) {
return ++n;
}
count = increase(count);
console.log(count); // 1
count = increase(count);
console.log(count); // 2
var count = 0;
// 비순수 함수
function increase() {
// 외부 상태에 의존하여 외부 상태를 변경
return ++count;
}
// 비순수 함수는 외부 상태(count)를 변경하므로 상태 변화를 추적하기 어려워진다.
increase();
console.log(count); // 1
increase();
console.log(count); // 2
순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고, 프로그램의 안정성을 높이려는 프로그래밍 패러다임