자바스크립트는 객체 기반의 프로그래밍 언어. 자바스크립트를 구성하는 거의 모든 것이 객체. 원시값을 제외한 함수, 배열, 객체는 모두 객체이다. 원시 타입은 단 하나의 값만을 나타내지만 객체 타입은 다양한 타입의 값을 하나의 단위로 묶어서 구성된 복합적인 자료구조이다. 원시값은 변경 불가능한 값이지만 객체 타입의 값은 변경이 가능하다.
객체는 0개 이상의 프로퍼티로 구성된 집합, 프로퍼티의 키와 값으로 구성된다.
자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있음. 함수는 일급 객체이기 때문에 값처럼 할당될 수 있으므로 프로퍼티 값이 함수일 경우, 메서드로 불린다. 객체 내부에 객체의 프로퍼티로서 참조되고 조작할 수 있는 함수를 메서드라고 한다 => 메서드는 객체에 묶여 있는 함수
자바스크립트는 '프로토타입 기반 객체지향 언어' '클래스 기반 객체지향 언어와 달리 다양한 객체 생성 방법을 지원한다.
1. 객체 리터럴:{}
형태의 리터럴로 객체를 생성한다.
2. Object 생성자 함수: Object 생성자 함수로 인스턴스 객체를 생성할 수 있다.
3. 생성자 함수: 임의의 생성자 함수를 통해 인스턴스 객체를 만들 수 있다.
4. Object.create 메서드를 사용해서 객체를 생성할 수 있다.
5. ES6 부터는 class를 활용하여 인스턴스 객체를 생성할 수 있다.
변수에 원시값을 갖는 변수를 할당하면 할당 받는 변수에는 할당하는 변수의 원시값이 복사되어 전달된다. 값은 독립적으로 다른 메모리 공간에 저장되어 각각 변경되어도 서로 영향을 미치지 않는다. => 값에 의한 전달
객체의 프로퍼티 개수는 정해져 있지 않아 동적으로 추가할 수 있고 삭제할 수 있다. 프로퍼티 값에도 제약이 없다. 객체는 원시값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘수 없다. 위와 같은 객체의 가변성의 성질 때문에 객체를 할당한 변수가 기억하는 메모리 주소를 통해 대신 참조값에 접근하는 방식을 쓸 수 있다.
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달된다. 참조값은 같은 메모리 주소를 가리키는 주소 값이므로, 한 변수의 객체를 변경하면 원본 객체 또한 변경된다. => 참조에 의한 전달
코드가 한 줄씩 순차적으로 실행되는 런타임에는 이미 함수 객체가 생성되어 있고, 함수 이름과 동일한 식별자에 할당까지 완료된 상태.
함수 선언문의 코드가 평가되고 실행되기 이전에 함수를 참조할 수 있고, 호출할 수 있음
함수 호이스팅: 함수의 선언문이 코드의 선단에 끌어 올려진 것처럼 동작하는 자바스크립트의 특이 동작
이에 반해 함수 표현식은, var 키워드로 생성한 변수에 할당됨. undefined로 초기화 되고 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화 된다.
var 키워드를 사용한 변수 선언문은 이전에 변수를 참조하면 변수 호이스팅에 의해 undefined로 평가되지만, 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호출하면 함수 호이스팅에 의해 호출이 가능하다.
유효범위라는 뜻을 식별자가 유효한 범위를 뜻한다.
자바스크립트 엔진은 스코프를 통해 어떤 변수를 참조해야 하는지 결정하기 때문에, 스코프는 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙이라 할 수 있다.
스코프는 크게 전역 스코프와 지역 스코프로 구분된다.
스코프는 상대적인 개념으로 전역이란 코드의 가장 바깥 영역을 의미. 전역 스코프에 변수를 선언하면 변수는 전역 스코프를 갖는 전역 변수가 된다. 전역 변수는 어디서든 참조할 수 있다.
지역이란 함수 몸체 내부를 말한다. 지역은 지역 스코프를 만들고, 지역 스코프에 변수를 선언 하면 지역 스코플를 갖는 지역 변수가 된다. 지역 변수는 자신의 스코프와 하위 ㅅ지역 스코프에서 접근할 수 있다.
함수를 어디서 호출했는 지가 아닌 어디서 정의했는지에 따라 함수의 상위 스코프를 결정하는 것이 정적 스코프 = 렉시컬 스코프이다.
생성자 함수는 new 연산자와 함께 호출되어 객체를 생성하는 함수를 의미한다. 생성자 함수에 의해 생성된 객체는 인스턴스라고 한다.
자바스크립트는 Object, String, Number, Boolean 등등 여러 내장 생성자 함수를 제공한다.
생성자 함수는 객체를 생성하기 위해 사용되지만, 반드시 Object 생성자 함수를 사용해 객체를 생성해야 하는 것은 아님 => 객체 리터럴을 통해서도 객체를 생성할 수 있기 때문
객체 리터럴에 의한 객체 생성 방식은 단 하나의 객체만을 생성하기 때문에 같은 프로퍼티를 갖는 여러 개의 객체를 생성해야 하는 경우 비효율적이다.
생성자 함수를 통해 객체를 생성한다면, 객체를 생성하기 위한 템플릿처럼 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성할 수 있다.
생성자 함수를 생성하는 과정은
1. 생성자 함수 선언
function Circle(radius) {}
2. 인스턴스 생성
const circle = new Circle(5);
this.getDiameter = function() {
return 2 * this.radius;
}