모던 자바스크립트 ( 14 ~ 18장 )

몽슈뜨·2023년 1월 20일
0

모던자바스크립트

목록 보기
3/3
post-thumbnail

2023.01.20

#지역 변수의 생명 주기
변수는 생물과 유사하게 소멸되는 생명 주기가 있다.

전역 변수의 생명주기는 애플리케이션의 생명주기와 같다.
하지만 함수 내부에 선언된 지역변수는 함수가 호출되면 생성, 종료하면 소멸한다

= 지역변수의 생명주기는 함수의 생명 주기와 일치한다.

할당된 메모리 공간은 더 이상 그 누구도 참조하지 않을 때 가비지 콜렉터에 의해 해제되어 가용 메모리 풀에 반환됨.

호이스팅은 스코프를 단위로 동작하며,
호이스팅은 변수 선언이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 말함.


#전역 변수의 생명 주기

var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 되어 생명 주기가 전역객체의 생명 주기와 일치해진다는것을 의미한다.
var 키워드로 선언한 전역변수는 웹페이지를 닫을 때까지 유효하다.


#전역 변수의 문제점
암묵적 결합
모든 코드가 전역 변수를 참조하고 변경할 수 있는 암묵적 결합을 허용한다.
변수의 유효범위가 크면 클수록 = 가독성이 나빠짐, 의도치 않게 상태가 변경될 수 있는 위험성도 같이 높아진다.

긴 생명 주기
전역 변수는 생명 주기가 길다. 메모리 리소스의 낭비도 심해진다. 

스코프 체인 상에서 종점에 존재
변수를 검색할 때 전역 변수가 가장 마지막에 검색된다는 것을 말한다.
전역 변수의 검색 속도가 가장 느리다.

네임스페이스 오염
자바스크립트의 가장 큰 문제점은 파일이 분리되어 있다 해도 하나의 전역 스코프를 공유한다는 것이다.
다른 파일 내에서 동일한 이름으로 명명된 전역변수, 함수가 같은 스코프 내에 존재할 경우
예상치 못한 결과를 가져올 수 있다.

전역 변수의 사용을 억제하는 방법
전역 변수를 반드시 사용해야 하는 이유가 없으면, 지역변수를 사용해 스코프를 좁혀야 한다.

#즉시 실행 함수
즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 된다.
(function () {
 var foo = 10;
}());
console.log(foo) // 참조 에러
(전역변수 생성안함, 라이브러리에 자주 사용)

#네임스페이스 객체
전역에 네임스페이스 역할을 담당할 객체를 생성, 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법이다.

var MYAPP = {}; //전역 네임스페이스 객체
MYAPP.name = 'Woo';
console.log(MYAPP.name) //Woo

혹은
네임스페이스 객체에 또 다른 네임스페이스 객체를 프로퍼티로 추가해서 네임스페이스를 계층적으로 구상 가능하다.

var MYAPP = {} // 전역 네임스페이스 객체
MYAPP.person = {
 name: 'Woo',
 adress: 'Uijeongbu'
}
console.log(MYAPP.person.name); // Woo


#모듈 패턴
모듈 패턴은 클래스를 모방, 관련있는 변수와 함수를 즉시 실행 함수로 감싸 하나의 모듈을 만들며,
클로저를 기반으로 작동한다.
특징으로는 전역변수의 억제, 캡슐화까지 구현가능하다.
#######
캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는것
캡슐화는 객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용하는데, 이를 정보 은닉이라 함.

모듈 패턴은 전역 네임스페이스 오염을 막는 기능은 물론 한정적이기는 하지만, 정보 은닉을 구현하기위해 사용한다.

var Counter = (function () {
 //private 변수
 var 티모 = 0;
 //외부로 공개할 데이터니 메서드를 프로퍼티로 추가한 객체를 반환함.
 return {
 increase() {
   return **티모;
 },
 decrease() {
   return --티모;
 }
}
}());

//private 변수는 외부로 노출되지 않음.

console.log(Counter.티모) //undefined
console.log(Counter.increase()) // 1
console.log(Counter.decrease()) // 0

#ES6 모듈 
ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.
확장자는 mjs를 권장하며, type="module" 어트리뷰트를 추가하면 된다.
구형 브라우저에는 동작하지 않아
Webpack등의 모듈 번들러를 사용하는것이 일반적이다.


let const 키워드와 블록 레벨 스코프

#var 키워드로 선언한 변수의 문제점

##변수 중복 선언 허용
var 키워드로 선언한 변수는 중복 선언이 가능하다.

##함수 레벨 스코프

var 키워드로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다.
-> var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수가 된다.

함수 레벨 스코프는 전역 변수를 남발할 가능성을 높인다.

##변수 호이스팅
var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작.
호이스팅에 의해 var 키워드로 선언한 변수는 변수 선언문 이전에 참조할 수 있다.
할당문 이전에 변수를 참조하면 언제나 undefined를 반환.

#let 키워드

##변수 중복 선언 금지
let i = 1;
fucntion () {
 let i = 2;
}
let 키워드로 이름이 같은 변수를 중복 선언하면 문법 에러가 발생한다.
##블록 레벨 스코프
let 키워드로 선언한 모든 코드블록(함수, if, for, while, try/catch 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.
##변수 호이스팅
let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작한다.
let 키워드로 선언한 변수는 "선언 단계""초기화 단계"가 분리되어 진행된다.
런타임 이전에 선언단계가 먼저 실행되나, 초기화 단계는 선언문에 도달했을때 실행된다.

하지만 let 키워드로 선언한 변수도 호이스팅이 발생한다.

let foo = 1; // 전역 변수
{
 console.log(foo); //참조 에러
 let foo = 2; //지역 변수
}

let 키워드로 선언한 변수도 여전히 호이스팅이 발생하기 때문에 참조 에러가 발생한다.

#전역 객체와 let
var 키워드로 선언한 전역 변수와 전역 함수, 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window 프로퍼티가 된다. 전역 객체의 프로퍼티를 참조할 때 window를 생략할 수 있다.

let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아니다., window.foo와 같이 접근할 수 없다.
let 전역 변수는 보이지 않는 개념적인 블록(전역 렉시컬 환경의 선언적 환경 레코드, 23"실행 컨텍스트")내에 존재하게 된다.

##const 키워드
const 키워드는 상수를 선언하기 위해 사용되나, 반드시 상수만을 위해 사용하지는 않는다.

##선언과 초기화
const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야한다.
const foo = 1;

let과 마찬가지로 블록레벨 스코프이며, 변수 호이스팅이 발생하지 않는것 처럼 동작한다.

##재할당 금지
const 키워드로 선언한 변수는 재할당이 금지됨.

##상수

변수의 상대 개념인 상수는 재할당이 금지된 변수

상수는 상태 유지와 가독성, 유지보수의 편의를 위해 적극적으로 사용해야함.

const로 선언된 변수에 원시값을 할당한 경우 원시 값은 변경할 수 없는 값이고 const 키워드에 의해 재할당이 금지되므로
할당된 값을 변경할 수 있는 방법은 없다.

또한 상수는 프로그램 전체에서 공통적으로 사용하여, 나중에 값이 변경되면 상수만 변경하면 되기에 유지보수성이 대폭 향상된다.
const 키워드와 객체

const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있다.
const 키워드는 재할당을 금지할 뿐 "불변"을 의미하지는 않는다.
-> 새로운 값을 재할당하는것은 불가능하나, 프로퍼티 동적 생성, 삭제, 값의 변경등을 통해 객체를 변경하는것은 가능하다.

##var vs let vs const
ES6을 사용한다면 var는 사용하지 말것
재할당이 필요한 경우에 한정해 let 키워드를 사용, 변수의 스코프를 좁혀라
변셩이 발생하지 않고 읽기 전용으로 사용하는 (재할당 필요없는 상수) 원시값과 객체에는 const 키워드를 사용한다.
const 키워드는 재할당을 금지하기에, let 키워드보다 안전함.

객체는 의외로 재할당하는 경우가 드문데, 변수를 선언할 때는 일단 const키워드를 사용하자.
후에 재할당이 필요하다면 let으로 바꿔도 늦진 않다.

#16장 프로퍼티 어트리뷰트 - 이 챕터는 보고 일단 알아두고, 다시 궁금해지면 올것.

프로퍼티 어트리뷰트를 이해하기 위해, 내부 슬롯과 내부 메서드의 개념을 설명하면
내부 슬롯과 내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는
의사 프로퍼티와 의사 메서드다.
ECMAScript 사양에 등장하는 이중 대괄호 ([[...]])로 감싼 이름들이 내부 슬롯과 내부 메서드다.

이 내부 슬롯과 내부 메서드는 자바스크립트 엔진의 내부 로직이므로 원칙적으로 접근을 허가하지 않으나
일부 내부 슬롯과 간접적으로 접근수단을 제공하기는 한다.

예를 들면 모든 객체는 [[prototype]]이라는 내부 슬롯을 갖는다.
내부 슬롯은 자바스크립트 엔진의 내부 로직이므로 원칙적으로 접근이 불가능하나,
[[Prototype]]의 경우 __proto__를 통해 간접적으로 접근이 가능하다.

const o = {};
// 내부 슬롯은 엔진 내부로직이므로 직접 접근 불가
o.[[Prototype]] // 문법 에러
// 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하기는 함.
o.__proto__ //Object.prototype

#프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.

프로퍼티의 상태란 값, 값의 갱신가능여부, 열거 가능여부, 재정의 가능여부를 말한다.

프로퍼티 어트리뷰트는 내부상태 값인 내부 슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]이다.

직접 접근할수는 없으나, Object.getOwnPropertyDescriptor 메서드를 통해 확인은 가능함.

const person = {
 name: 'Lee'
};

//프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다.
console.log(Object.getOwnPropertyDescriptor(person, 'name'));
// {value: "Lee", writable: true, enumrable: true, configurable: true}

Object.getOwnPropertyDescriptor메서드는 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크럽터 객체를 반환한다.

데이터 프로퍼티와 접근자 프로퍼티

데이터 프로퍼티
키와 값으로 구성된 일반적인 프로퍼티이며, 지금까지 살펴본 모든 프로퍼티는 데이터 프로퍼티이다.
접근자 프로퍼티
자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티다.
256p
##표 참고

접근자 프로퍼티
접근자 프로퍼티는 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티다.

257p
## 표 참고

접근자 함수는 getter/setter 함수 라고도 부른다. (자바의 그것) getter와 setter 함수를 모두 정의할수도,
하나만 정의할수도 있다.

#프로퍼티 정의
프로퍼티 값을 갱신 가능하도록 할 것인지, 프로퍼티를 재정의 가능하도록 할 것인지 정의 가능하다.


객체 변경 방지
구분		메서드			프로퍼티 추가	 삭제	 값 읽기	쓰기	어트리뷰트 재정의
객체 확장 금지	Object.preventExtensions	 X		  O	    O	  O	 O
객체 밀봉		Object.seal		 X		  X	    O	  O	 X
객체 동결		Object.freeze		 X		  X	    O	  X	 X


확장 금지

확장이 금지된 객체는 프로퍼티 추가가 금지된다.

객체 밀봉
밀봉된 객체는 읽기와 쓰기만 가능

객체 동결
동결된 객체는 읽기만 가능

불변 객체
변경 방지 메서드들은 직속 프로퍼티만 변경이 방지되고 중첩 객체까지는 영향을 주지는 못한다.
따라서 Object.freeze 메서드로 객체를 동결하여도 중첩 객체까지는 동결할 수 없음.

객체의 중첩 객체까지 동결하여 변경이 불가능한 읽기 전용의 불변객체를 구현하려면
객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드를 호출해야 함.



17장 생성자 함수에 의한 객체 생성

Object 생성자 함수
new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환한다.
-> 생성 이후 프로퍼티 또는 메서드 추가, 객체를 완성가능

생성자 함수란?
연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수를 말함.
생성자에 의해 생성된 객체를 인스턴스라고 부름.

자바스크립트는 Obejct 생성자 함수 외, String, Number, Boolean Function, Array, Date, RegExp, Promise 등의 빌트인 함수를 제공.


#생성자 함수
객체 리터럴에 의한 객체 생성 방식의 문제점 
객체 리터럴에 의한 객체 생성은 단 하나의 객체만 생성한다.

그렇기 때문에 객체가 한 두개라면 넘어가겠지만, 수십개 수백개의 객체를 생성해야 한다면
생성자를 통해 생성해주는것이 바람직하다.

생성자 함수에 의한 객체 생성 방식의 장점
생성자 함수에 의한 객체 생성 방식은 마치 객체를 생성하기 위한 템플릿(클래스)처럼 생성자 함수를 사용, 
프로퍼티 구조가 동일한 객체 여러개를 간편하게 생성할 수 있다.

**this
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이며, this가 가리키는 값, this 바인딩은
함수 호출 방식에 따라 동적으로 결정됨.

함수 호출 방식		this가 가리키는 (this 바인딩)
일반 함수로서 호출		전역 객체
메서드로서 호출		메서드를 호출한 객체(마침표 앞의 객체)
생성자 함수로서 호출	생성자 함수가 (미래에) 생성할 인스턴스

new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
만약 new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수가 아닌 일반 함수로 동작한다.

생성자 함수의 인스턴스 생성 과정
생성자 함수의 역할은
프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿으로써 동작하여
인스턴스를 생성하는 것과 생성된 인스턴스를 *초기화*(인스턴스 프로퍼티 추가 및 초기값 할당)하는 것이다.

인스턴스 생성 : 필수 / 초기화 : 옵션

인스턴스 생성과 this 바인딩
암묵적으로 빈 객체가 생성됨 
생성자 함수가 생성한 인스턴스이며,
이 객체의
인스턴스는 this에 바인딩된다.
생성자 함수 내부에 this가 생성자 함수가 생성할 인스턴스를 가리키는 이유는 바로 이것이다.

**바인딩?
식별자와 값을 연결하는 과정

function Circle(raduis) {
 // 1. 암묵적으로 인스턴스가 생성되고 this가 바인딩된다.
 console.log(this); // Circle {}
 // 2. this에 바인딩 되어있는 인스턴스를 초기화한다.
 // 오버라이딩  
 this.raduis = radius;
 this.getDiameter = function () {
  return 2 * this.raduis;
 };
}

인스턴스 초기화
생성자 함수에 기술되어 있는 코드가 한줄씩 실행되어 this에 바인딩 되어있는 인스턴스를 초기화한다.
this에 바인딩되어 있는 인스턴스에 프로퍼티나 메서드를 추가하고 생성자 함수가 인수로 전달받은 초기값을
인스턴스 프로퍼티에 할당하여 초기화하거나, 고정값을 할당한다.

인스턴스 반환
생성자 함수 내부의 모든 처리가 끝나면, 완성된 인스턴스의 바인딩된 this가 암묵적으로 반환된다.
? this가 아닌 다른 객체를 명시적으로 반환하면 this가아닌 명시한 객체가 반환됨.
? 하지만 명시적으로 원시 값을 반환하면 원시 값 반환은 무시되고, 암묵적으로 this가 반환된다.

일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.

따라서 내부 슬롯, 메서드는 물론, 함수 객체만을 위한
[[Enviroment]], [[FormalParameters]] 등의 내부 슬롯,
[[Call]], [[Construct]] 같은 내부 메서드를 추가로 가지고있다.

이때 함수가 일반 함수로써 호출되면 함수 객체의 내부메서드 [[Call]]이 호출되고, new 연산자와 함께 생성자 함수로써 호출되면
내부 메서드 [[Construct]]가 호출된다.

내부 메서드 [[Call]]을 갖는 객체를 callable, 내부 메서드 [[Construct]]를 갖는 함수 객체를 constructor, [[Construct]]를 갖지 않는 함수 객체를 non-constructor라고 부른다.

callable = 호출할수 있는 객체, 함수를 말함
constructor = 생성자 함수로써 호출할수 있는 함수
non-constructor는 객체를 생성자 함수로써 호출할 수 없는 함수를 의미.

모든 함수 객체는 callable이지만, 모든 함수 객체가 constructor인 것은 아님.


constructor: 함수 선언문, 함수 표현식, 클래스(클래스도 함수)
non-constructor: 메서드(ES6 메서드 축약 표현), 화살표 함수

new 연산자와 함께 함수를 호출하면 해당 함수는 생성자 함수로 동작

함수 객체의 내부 메서드 [[Call]]이 호출되는 것이 아니라 [[Construct]]가 호출됨.new 연산자와 함께 호출하는 함수는 non-constructor가 아닌 constructor여야 함.


new.target
생성자 함수가 new 연산자 없이 호출되는것을 방지하기 위해 파스칼 케이스를 사용.
하지만 실수는 언제 어디서나 발생, ES6에서는 new.target을 지원

new.target은 this와 유사하게 생성자인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용되며 메타 프로퍼티라고 부름.
함수 내부에서 new.target을 사용하면 new 연산자와 함께 생성자 함수로써 호출되었는지 확인할 수 있음.

new 연산자와 함께 생성자 함수로써 호출되면 함수 내부의 new.target은 함수 자기 자신을 가리키며
new 연산자가 없이 일반함수로 호출되면 함수 내부의 new.target은 undefined이다.
확인방법 -> 재귀호출

스코프 세이프 생성자 패턴
-> IE에서는 new.target 지원안함, 이때 사용가능한 패턴.


#일급 객체

일급 객체는 다음의 조건을 만족한다.
1. 무명의 리터럴로 생성할 수 있다. 즉 런타임에 생성이 가능.
2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있음
3. 함수의 매개변수에 전달할 수 있음
4. 함수의 반환값으로 사용할 수 있다.

자바스크립트의 함수는 위의 조건을 전부 만족함. = 함수는 일급 객체다.

함수는 값을 사용할 수 있는 곳 이라면 어디서든지 리터럴로 정의가 가능,
런타임에 함수객체로 평가됨.

함수는 객체이지만 일반 객체와는 차이가 있는데, 일반 객체는 호출할수 없지만
함수 객체는 호출할 수 있음.
함수 객체는 일반 객체엔 없는 함수 고유의 프로퍼티를 소유함.

#함수 객체의 프로퍼티
함수는 객체이며, 함수도 프로퍼티를 가질 수 있다.

Object.prototype 객체의 __prototype__ 접근자 프로퍼티는 모든 객체가 사용할 수 있음.


arguments 프로퍼티
함수 객체의 arguments 프로퍼티 값은 arguments 객체다. 
arguments 객체는 함수 호출 시 전달된 인수들의 정보를 담고 있는 순회 가능한 (이터러블) 유사 배열 객체이며, 함수 내부에서 지역 변수처럼 사용된다.

## 모든 초과된 인수는 arguments 객체의 프로퍼티로 보관됨. (사라지지 않음)
arguments 객체는 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하다.

caller 프로퍼티
caller는 비표준 프로퍼티, 함수 자신을 호출한 함수를 가리킴.

length 프로퍼티
객체의 length 프로퍼티는 함수를 정의할 때 선언한 매개변수의 개수를 가리킨다.

name 프로퍼티
함수 객체의 name 프로퍼티는 함수 이름을 나타낸다.
name 프로퍼티는 ES6에서 정식 표준이 되었다. (그렇기때문에 ES5, 6의 동작을 달리함. 5는 빈 문자열을 값으로, 6에서는 함수 객체를 가리키는 식별자를 값으로 갖음)

__proto__ 접근자 프로퍼티
모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는데
[[Prototype]] 내부 슬롯은 객체지향 프로그래밍의 상속을 구현하는 프로토타입 객체를 가리킨다.
# 19장 참고

prototype 프로퍼티

prototype 프로퍼티는 생성자 함수로 호출할 수 있는 함수 객체, 즉 constructor만이 소유하는 프로퍼티이다.
일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 prototype 프로퍼티가 없다.

19장 프로토타입

자바스크립트는 명령형, 함수형, 프로토타입 기반, 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어.

자바스크립트는 클래스 기반 객체지향 프로그래밍 언어보다 효율적이며, 프로토타입 기반의 객체지향 프로그래밍 언어.

자바스크립트는 객체 기반의 프로그래밍 언어이며, 자바스크립트를 이루고 있는 거의 모든것이 객체임.
원시타입을 제외, 나머지 값은 모두 객체임.

객체지향 프로그래밍 OOP

여러개의 독립적 단위, 객체의 집합으로, 프로그램을 표현하려는 프로그래밍 패러다임을 말한다.
객체지향 프로그래밍은 실세계의 실체(사물, 개념)을 인식하는 철학적 사고를 프로그래밍에 접목하려는 시도에서 시작했다.
실체는 특징이나 성질을 나타내는 속성을 가지고 있고, 이를 통해 실체를 인식하거나 구별할 수 있다.
사람은 이름 나이 신장 등.. 다양한 속성을 갖는데, 속성을 구체적으로 표현하면 이 사람은 다른 사람과 구별하여 인식이 가능하다.

이때 프로그램에서는 "이름", "주소"만 관심이 있다고 가정하면 프로그램에서 필요한 속성만 간추려 내어 표현하는것을
추상화라고 한다.

이처럼 속성을 통해 여러개의 값을 하나의 단위로 구성한 복합적인 자료구조를 객체라고 하며
OOP는 독립적인 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임이다.

객체지향 프로그래밍은 상태를 나타내는 데이터와 상태 데이터를 조작할수있는 동작을 하나의 논리단위로 묶어 새악ㄱ한다.

-> 객체는 상태 데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조 이다.


23-01-20

#14장 전역 변수의 문제점

변수는 생물과 유사하게 생성되고 소멸되는 생명 주기가 있다.
변수는 자신이 선언된 위치에서 생성되고 소멸한다.

지역 변수의 생명 주기는 함수의 생명 주기와 일치한다.

호이스팅은 스코프를 단위로 동작
	변수 선언이 스코프의 선두로 끌어 올려진 것처럼
	동작하는 자바스크립트 고유의 특징
	
전역변수의 문제점
  1.암묵적 결합
	모든 코드가 전역 변수를 참조하고 변경할 수 있는 허용

  2.긴 생명 주기
  
  3.스코프 체인 상에서 종점에 존재
	변수를 검색할 때 전역 변수가 가장 마지막에 검색되는것을 말한다
	전역 변수의 검색 속도가 가장 느리다
	
  4.네임스페이스 오염
	파일이 분리되어 있다 해도 하나의 전역 스코프를 공유한다
	따라서 다른 파일 내에서 동일한 이름으로 명명된 전역변수나
	전역 함수가 존재할 경우 문제가 발생한다.
	
변수의 스코프는 좁을수록 좋다.

캡슐화 : 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고
	조작 할 수 있는 동작 메서드를 하나로 묶는 것
	
객체지향 클래스를 구성하는 맴버 
	: public, private, protected // 접근제한자


# 15let,const 키워드와 블록레벨 스코프

var : 중복 선언 가능
let : 중복 선언 불가능, 선언단계,초기화단계가 분리되어 진행
const : 재할당 금지

스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는
구간을 일시적 사각지대(TDZ)라고 부른다

let,const 키워드는 선언한 전역 변수는
전역 객체 window의 프로퍼티가 아니다

const 키워드로 선언한 변수는 반드시 선언과 동시에
초기화 해야된다.


#16장 프로퍼티 어트리뷰트 // 멤5

내부슬롯의 경우 __proto__를 통해 간접적 접근 가능

프로퍼티 어트리뷰트
	프로퍼티를 생성할 때 프로퍼티의 상태를 나나태는
	프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
	
데이터 프로퍼티
	키와 값으로 구성된 일반적인 프로퍼티
	
접근자 프로퍼티
	자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을
	읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
	
프로토타입 19장에서 자세히 보자


# 17장 생성자 함수에 의한 객체 생성

this :
	객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수
	this가 가르키는값.this바인딩은 함수 호출 방식에 따라
	동적으로 결정된다.
	
new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작
함수를 호출하지않으면 생성자 함수가 아니라 일반함수로 동작

바인딩 :
	식별자와 값을 연결하는 과정을 의미
	변수선언은 변수이름(식별자)과 확보된 메모리 공간의 주소를
	바인딩 하는것이다. this 바인딩은 thisthis가 가리킬 객체를
	바인딩 하는것이다.

함수는 객체 이므로 일반 객체와 동일하게 동작 할 수 있다.

함수는 객체 이지만 일반 객체와 다르다.
일반 객체는 호출 할수 없지만 함수는 호출 할 수 있다.

constructor :
	함수 선언문, 함수 표현식, 클래스

non-constructor :
	메서드(ES6메서드 축약 표현), 화살표 함수
	
new.target :
	this와 유사하게 constructor인 모든 함수 내부에서 암묵적인
	지역변수와 같이 사용되며, 메타 프로퍼티라고 부른다
	
스코프 세이프 생성자 패턴 :
	ES6에서 도입된 최신 문법,
	new.target을 사용할 수 없는 상황이라면
	세이프 생성자 패턴을 사용할 수 있다.
	
# 18장 함수와 일급 객체

일급 객체 :
	1.무명의 리터럴로 생성할 수 있다. <런타임에 생성이 가능하다>
	2.변수나 자료구조(객체,배열 등)에 저장할 수 있다.
	3.함수의 매개변수에 전달할 수 있다.	<-중요
	4.함수의 반환값으로 사용할 수 있다.
	
함수가 일급 객체라는 것은 함수를 객체와
동일하게 사용할 수 있다는 의미다.

함수는 객체다. 따라서 프로퍼티를 가질 수 있다.
브라우저 콘솔에서 console.dir 사용하여 함수 객체의 내부를 볼 수 있다.

프로퍼티 어트리뷰트 / getOwnProperttyDescriptors <- 검색

arguments, caller, length, name, prototype
프로퍼티는 모두 함수 객체의 데이터 프로퍼티다.

arguments 프로퍼티 :
	유사배열 객체이며, 지역변수 처럼 사용된다.
	함수 외부에서는 참조 할 수 없다.
	
name 프로퍼티 :
	함수 이름고 함수 객체를 가리키는 식별자는 의미가 다르다
	
profile
개발자되면 맥북사줄께

0개의 댓글