ES5 Seminar 정리! #양재동 코드랩
1.
Javascript의 기능 (Control)
- DOM : HTML, CSS 컨트롤
- HTML5 API : File, IndexedDB
- 그래픽 : SVG, Canvas, WebGL
- 통신 : XMLHttpRequest, Socket
책 추천 - 몰입 자바스크립트!, EcmaScript6
2.
함수 형태
빌트인(Built-in) function 오브젝트
- 내장 함수
- Array.isArray()
- Array.prototype.forEach()
function 오브젝트
- function book () {}
- var book = function() {...}
function 인스턴스
- new Book(), new 사용 ( 대문자 사용 )
- Book.prototype의 프로퍼티 사용 (이걸 이해하지 못하면 ES6의 많은 부분을 포기하는 것과 같다!)
▶ 오브젝트와 인스턴스의 차이
- function 오브젝트는 단일 수행이지만 function 인스턴스는 동일한 메소드를 가진 인스턴스를 생성하고 그 값들을 조작하여 수행할 수 있다.
3.
function 오브젝트
호출 형태
- function sports() {...};
- sports();
▶ 함수가 오브젝트여야 호출이 가능하다
▶엔진이 function 타입 키워드를 만나면
- 빌트인 function 오브젝트의 prototype에 연결된 프로퍼티(call, bind 등)를 결합해 function 오브젝트를 알맞게 생성한다.
- 이렇게 생성한 오브젝트를 sports 변수에 할당한다.
▶ function 오브젝트 저장 형태
- function 명령어로 생성한 function 오브젝트를 { name : value } 형태로 저장한다.
ex) { sports : function 오브젝트 }
- 함수를 호출하면 함수 이름으로 저장된 오브젝트를 탐색하고 value 값을 구한 뒤 value 타입이 function 오브젝트이면 호출한다.
- javascript에선 타입을 컴파일할 때 결정하기 때문에 밑에서 얼마든지 key 값의 타입을 바꿀 수 있다. java나 c++ 같은 경우엔 타입을 프리 컴파일 과정에서 미리 결정을 해서 이런 오류가 발생할 가능성이 적지만 javascript의 자료형은 가변적이기 때문에 조심해야 한다.
▶ 함수가 호출되면 엔진은 { name : {{ name: value }, {..}} } 형태의 프로퍼티를 조합하여 실행 환경을 설정하고 함수 코드를 실행한다.
따라서 { name : value } 형태에 맞추어 생각을 전환할 필요가 있다.
▶ 어찌보면 HTML이나 CSS도 { name : value } 구조라고 볼 수 있다.
div = name
element = value
class = class
id = id
4.
객체지향언어
javscript는 EcmaScript 스펙에 나와있듯이 객체지향언어이다.
그래서 function 오브젝트를 객체로 인식하고 접근할 필요가 있다.
OOP의 개념을 이해해야 한다.
ES6는 OOP의 개념을 정확히 구현할 수 있도록 환경을 조성했다.
그렇기에 더더욱 OOP 개념에 따라 코드를 작성해야 한다.
5.
아키텍처, 메커니즘
아키텍처 : Architecture
- 목적을 가진 구조
- 자바스크립트 목적을 달성하기 위한 구조
메커니즘 : Mechanism
- 목적을 달성하기 위한 방법
- 목적에 따라 방법, 기준이 달라질 수 있음
아키텍처와 메커니즘 이해 필요
6.
javascript 목적
javascript는 프로그래밍 언어다. 언어의 목적은 소통이다.
프로그램을 통해 javscript 엔진과 소통하자.
문법을 지켜야 소통이 가능하다.
7.
function 오브젝트 예제
(1) function 오브젝트 생성
- 코드 : function sports(){};
(2) sports 오브젝트에 prototype 오브젝트 ㅊㅁ부
- 코드 : {
sports : {
prototype : { ... }
}
}
(3) prototype에 constructor 프로퍼티 첨부
- 코드 : {
sports : {
prototype : { ... },
constructor: sports 전체 참조
}
}
(4) prototype에 _proto_ 오브젝트 첨부
- ES5 스펙에 _proto_를 기술하지 않음
- ES6 스펙엔 _proto_ 기술, 엔진 사용 정의
- ES5 기준에선 표준이 아님
- 코드 : {
sports : {
prototype : { ... },
constructor: sports 전체 참조, __p
__proto__ : { ... }
// 엔진이 사용하는 key이기에 개발자는 건드리지 말 것!
}
}
(5) 빌트인 Object 오브젝트의 prototype에 연결된 프로퍼티를 결합해 Object 인스턴스를 생성한다. 생성한 Object 인스턴스를 prototype._proto_에 상속한다. (함수를 선언할 때마다 불필요하게 상속하기 때문에 설계 미스이다.) 마지막으로 sports 오브젝트에 _proto_ 오브젝트 첨부한다.
- 코드 : {
sports : {
prototype : { ... },
constructor: sports 전체 참조, __p
__proto__ : {
Object.prototype.call : { ... },
Object.prototype.apply : { ... },
Object.prototype... : { ... }
}
}
}
(6) 빌트인 function 오브젝트의 prototype에 연결된 프로퍼티로 function 인스턴스를 생성한 후 __proto__에 첨부한다.
- 코드 : {
sports : {
prototype : { ... },
constructor: sports 전체 참조, __p
__proto__ : {
function() {
Object.prototype.call : { ... },
Object.prototype.apply : { ... },
Object.prototype... : { ... }
}
}
}
}
(7) Math, JSON, Global Object를 제외한 모든 오브젝트는 prototype이 있다.
8. 내부 프로퍼티 분류
- 공통 프로퍼티, 선택적 프로퍼티
▶공통 프로퍼티 :
모든 오브젝트에 공통으로 설정되는 프로퍼티
▶선택적 프로퍼티 :
오브젝트에 따라 선택적으로 설정되는 프로퍼티, 해당되는 오브젝트에 설정
9. 함수 정의
함수 정의
- 함수가 실행될 수 있도록 javascript 문법에 맞게 작성
함수 정의 형태
- 함수 선언문 (function declaration)
- 함수 표현식 (function expression)
- new function(param1, param2, body)
--- 문자열로 작성 -> 해킹 위험
▶ 함수 선언문
- function [function] : function 키워드
- 식별자 [String] : 함수 이름
- 파라미터 [Any] : 파라미터 리스트
- 함수 블록 [Object] : 실행 가능한 코드
- 반환 [function] : 생성한 function 오브젝트
▶ 함수 표현식
- var name = function() {};
- function 오브젝트를 생성하여 변수에 할당
10. 엔진 해석
javascript는 script 언어이다. script 언어는 작성된 코드를 위에서부터 한 줄 씩 해석(컴파일, 실행)하지만 javascript는 조금 다르다.
함수 형태에 따라 해석 순서가 다르고 중간에 있는 코드가 먼저 해석될 수 있다.
먼저 전체 함수 선언문을 차례대로 해석한다.
- function sports(){};
이어서 차례대로 함수 표현식을 해석한다.
- var sports = function(){};
ex)
baseball(); // undefined.
//함수 표현식은 변수에 undefined로 할당되기 때문
▶ 코드 해석 단계
(1) 함수 선언문 해석 : 한번 쭉 내려가면서 함수를 탐색한다.
- function sports(){};
- function soccer(){};
(2) 변수 초기화
- var player = undefined;
- var baseball = undefined;
(3)
var player = 11;
var baseball = function() {};
11. 함수 선언문 오버라이딩
▶ 오버라이딩(Overriding)
- 함수 이름이 같을 때 함수 코드 대체(replace)
▶ 자바스크립트는 파라미터, 수, 데이터 타입을 체크하지 않는다.
모두 { name : value }로 저장하기 때문이다.
▶ 대체되는 상황
(1) 초기화 단계에서 위에서부터 함수 선언문을 function 오브젝트로 생성한다.
(2) 아래에 같은 이름의 함수 선언문이 있으면 아래의 함수 선언문이 호출된다.
ex)
12. 함수 파라미터
파라미터(Parameter) 상호 관계
- 매개 변수
- 호출하는 함수 : 값 전송
- 호출받는 함수 : 전송된 값을 받음
파라미터 작성
- 호출하는 함수의 파라미터에 값 작성
- 호출받는 함수의 파라미터에 이름 작성
파라미터 값 처리
- 호출한 함수에서 보낸 값을 호출 받는 함수의 순서에 따라 처리
(엔진은 파라미터 순서로 값을 mapping 한다.)
파라미터 수가 유동적이라면 arguments를 사용해도 된다.
arguments[0] : 파라미터의 첫번째 값
그러나 ES6부터 rest parameter 문법이 생겼고 arguments는 거의 쓰지 않는다.
▶ arguments 값 반환
호출한 함수의 파라미터 값 타입 - 문자열, 숫자, 배열, 오브젝트 등
매커니즘
- 파라미터 순서에서 0부터 인덱스를 부여하여 key로 사용하고
파라미터로 받은 값을 value에 설정한다
- { 0 : value, 1 : value }
* 결론 : for()문 사용
- 파라미터가 배열일 때 for~in 문으로 읽으면 length 프로퍼티를 제외시키는 코드가 필요하기 때문이다.
Array-like
- key 값이 0부터 1씩 증가
- length 프로퍼티가 있어야 함
- 객체지만 인덱스값을 가지고 증가하기에 거의 배열 같은 친구
=> 이러한 연유로 ES6에선 for~of 문법이 나오게 된다.
▶ 엔진 처리
(1) 함수 호출
(2) 파라미터에 값 할당
(3) arguments 오브젝트 생성
(4) arguments 오브젝트에 파라미터 값 설정
(5) 함수 코드 실행
12. 스코프
Scope : 함수가 실행될 때 영향을 받는 범위.
ex) indexOf()의 스코프
(1) indexOf()는 String 오브젝트에 존재
- String 오브젝트가 indexOf()의 스코프
- indexOf()는 문자열을 처리하는 String 오브젝트의 영향을 받음
(2) Number 오브젝트에서 indexOf()를 호출하면 에러
Number 오브젝트에 indexOf()가 없기 때문이다.
Number 오브젝트가 indexOf()의 스코프가 아니기 때문이다.
▶ 사용 목적
(1) 범위 제한
- 신속한 검색 및 접근
- 스코프 안에서 우선 검색
(2) 같은 프로퍼티 이름 사용 가능
- String 오브젝트의 indexOf()
- Array 오브젝트의 indexOf()
(3) 오브젝트로 보면 오브젝트가 다르지만 함수에서 보면 스코프가 다르다. 실행될 때 함수의 스코프에서 검색하며 함수 안에서 밖으로 나가는 개념이다.
▶ 스코프 구조
- function 오브젝트를 생성할 때.
- 함수를 호출할 때 설정하는 게 아니다. 이를 정적 스코프라고 함.
- function 안의 코드에 대해서는 구조를 만들지 않는다.
*참고 : 동적 스코프란 함수를 호출할 때 설정하는 스코프를 의미한다. ES5에서 유일하게 동적 스코프를 허용하는 함수가 eval()다. 함수를 호출할 때마다 스코프를 형성하기 때문에 부담스럽다.
13. 글로벌 프로젝트
프로그램의 시작점
- 빌트인 오브젝트
글로벌 오브젝트 특성
(1) 전체 프로그램을 통해 하나만 존재
- 전체 프로그램 : 모든 <script>에 작성한 코드
(2) 오브젝트 이름을 작성하지 않고 함수를 호출하면 글로벌 오브젝트로 간주
글로벌 오브젝트 생성
(1) 첫 번째 <script>에서 한 번만 생성
- 자바스크립트 실행 환경 설정
(2) <script>의 프로그램 실행 전에 생성
new 사용 불가
- 인스턴스 생성 불가
▶ 글로벌 스코프
- 전체를 통해 하나만 존재하므로 스코프도 하나
- 글로벌 오브젝트와 글로벌 스코프가 같음
- 스코프가 전체이므로 모든 코드에서 사용 가능
* 최상위 스코프
- 함수에서 보면 최종 검색 스코프
- 검색한 프로퍼티가 없으면 undefined 반환
▶ 지역/글로벌 함수
- 지역함수 : 함수 안에서 var 키워드를 사용한 함수와 함수 선언문
- strict 모드일 때 -> var 키워드를 사용하지 않고 함수를 선언하면 에러 발생
* 글로벌에서 var 키워드를 사용하지 않으면 delete가 실행된다.
* 되도록 글로벌, 지역에 관계없이 var 키워드를 사용하자.
▶ 변수 사용(접근)
- 글로벌 변수 : 어느 위치에서도 변수 사용 가능
- 지역 변수 : 함수 안으로 들어가야 변수 접근 가능. 함수 외부에서 직접 사용 불가
14. 바인딩
바인딩(binding)
구조적으로 결속된 상태로 만드는 것
대상 - 오브젝트와 프로퍼티 이름
var get = {
... qty : value,
... price: value
};
바인딩 목적
- 스코프 결정
- 스코프에서 이름 식별
바인딩 시점 분류
- 정적 바인딩(Lexical, Static Binding)
- 동적 바인딩(Dynamic Binding)
스코프 체인
- 스코프가 상하구조로 연결된 개념/구조
- 스코프 체인을 사용하여 근접한 스코프에서 프로퍼티(함수, 변수) 검색
- ES3에서 채용
ES5에서 scope chain 개념이 폐지되었다.
- 렉시컬 환경(Lexical Environment) 개념 사용
▶ 바인딩 시점
* 정적 바인딩
(1) 초기화 단계에서 바인딩
(2) 함수 선언문 이름으로 바인딩
(3) 변수, 함수 표현식 이름으로 바인딩
(4) 대부분 정적 바인딩
(5) 값은 바인딩 대상이 아님
* 동적 바인딩
- 실행 단계에서 바인딩
- eval() 함수, with 문
▶ 바인딩 시점의 중요성
- 바인딩할 때 스코프가 결정되기 때문이다.
* function 오브젝트 생성 시점에 스코프가 결정된다.
- 인식한 스코프를 [[Scope]]에 설정하고
- 정적 바인딩은 [[Scope]]를 스코프로 사용한다.
- 스코프는 변경되지 않는다.
* 같은 단계의 모든 함수의 스코프가 같다.
▶ 프로퍼티 검색 방법
* [[Scope]] 프로퍼티에서 검색
엔진 해석 순서
-> 변수 생성 및 함수 생성 (key 값) -> 스코프 설정 -> (value) 값 할당 -> 함수 호출 -> 파라미터 값 할당 및 arguments 생성 -> 함수 실행
16. 렉시컬 환경
(1) 함수가 사용할 함수, 변수를 렉시컬 환경에 설정한다.
- 오브젝트, 변수, 다른 함수 참조가 가능하다.
(2) 함수가 구조적 환경에서 독립적으로 실행하기 위한 매커니즘 제공
초기화 단계에서 해석한 모든 함수와 변수를 { key : value } 형태로 저장한다.
▶ 렉시컬 환경 생성 : function, with, try ~ catch 문에서 생성됨
▶ 렉시컬 환경 구성 형태
- 렉시컬 환경(LE) = {
... 환경 레코드(ER: Environment Record) : {
sports: "농구",
member: "5명"
} ,
...외부 렉시컬 환경 참조
(OLER: Outer Lexical Environment Reference) : {
play: function() {},
values: [12, 34, 56]
}
}
▶ 외부 렉시컬 환경 참조
장점
- 근접한 렉시컬 환경의 논리적 연결을 통해, 현재 렉시컬 환경에 영향을 미치지 않으면서, 1단계 밖 스코프로 이동하지 않고 프로퍼티 사용
▶ 검색 메커니즘
1. 프로퍼티 검색 순서 방법
▶ 글로벌 환경
- 글로벌 오브젝트를 위한 렉시컬 환경
- 렉시컬 환경과 형태가 같음
특징
- 동적으로 함수와 변수 바인딩
- 함수에서 var 키워드를 사용하지 않고 함수/변수를 사용
17. 실행 콘텍스트
생성 시점
- 실행할 수 있는 코드를 만났을 때
실행할 수 있는 코드 유형
- 함수 코드(function code)
- 글로벌 코드(global code)
- eval 코드(eval code)
코드 유형 분리 이유
- 실행 컨텍스트에서 처리 방법과 환경이 다르기 때문이다.
- 함수 코드 : 렉시컬 환경
- 글로벌 코드 : 글로벌 환경
- eval 코드 : 동적 환경
18. 환경 컴포넌트
환경 컴포넌트 구성
- 렉시컬 환경 컴포넌트와 변수 환경 컴포넌트 지칭
19 . this 바인딩 컴포넌트
목적
- this로, 호출한 함수가 속한 오브젝트의 프로퍼티에 접근
접근 메커니즘
1. 호출한 함수가 속한 오브젝트를 참조할 수 있도록 this 바인딩 컴포넌트에 호출된 함수가 속한 오브젝트 참조 설정
2. obj.sports() 형태에서 this로 obj 참조
3. obj의 프로퍼티가 변경되면 동적으로 참조
4. obj를 this 바인딩 컴포넌트에서 참조할 수 있도록 설정
▶ this와 strict 모드
1. 글로벌 오브젝트에서 오브젝트를 작성하지 않고 함수를 호출하면
- this 바인딩 컴포넌트에는 undefined가 설정된다.
- strict 모드가 아닐 경우에는 this가 글로벌 오브젝트인 window를 참조한다.
20. Constructor
▶ Constructor 프로퍼티
- Function 오브젝트를 생성할 때 설정되며
- 생성하는 Function 오브젝트를 참조하도록 설정
- prototype에 연결되어 있음
개인 경험
- constructor가 없더라도 인스턴스가 생성됨
- 엔진에서 이를 고려하여 생성하는 것으로 생각됨
- 하지만 필요하지 않다는 의미는 아님
- ES6에서 constructor가 중요하므로 이해가 필요하다.
▶ property
- 목적 :
(1) 프로퍼티 연결을 통한 프로퍼티 확장
(2) 생성한 각 인스턴스에서 prototype의 프로퍼티 공유
(3) 상속 : 다른 function 인스턴스를 연결
- 프로퍼티 확장
(1) prototype에 프로퍼티 {key : value}를 연결하여 확장
- 프로퍼티 공유
(1) prototype에 연결된 프로퍼티로 인스턴스 생성
(2) 인스턴스에서 prototype에 연결된 프로퍼티 값 공유
21. 오브젝트 반환
new 연산자로 인스턴스를 생성할 때
- 생성자 함수에 return 문을 작성하지 않으면 인스턴스를 반환한다.
- 생성자 함수에 return 문을 작성하면 표현식 평가 결과에 따라 인스턴스가 반환되지 않을 수도 있다.
22. call()과 this
- 예제
23. bind()와 this
- 예제
24. 캡슐화
캡슐화
- 객체의 메서드와 프로퍼티를 외부에 숨김
- 처리 방법은 숨기고 사용할 수 있는 메서드와 파라미터를 외부에 공개
자바스크립트의 캡슐화
- 함수 안의 함수를 외부에서 호출 불가하게 하기
- 지역 변수 값을 외부에서 접근 불가하게 하기
- source가 오픈되는 것과 exe 파일의 차이가 있음
25. 다형성
자바스크립트의 다형성
- 파라미터 수와 데이터 타입에 영향을 받지 않음
- 메소드 이름이 같으면 나중에 작성한 것으로 대체됨
26. 상속(유전)
상속(유전)
- 상속의 목적은 객체의 재사용에 있다.
- 목적에 맞는 객체를 내 객체에 포함시키는 것
- 다중상속
자바스크립트의 상속(유전)
- 오브젝트{}와 오브젝틀르 병합
- 함수의 prototype에 인스턴스 연결
- 다중상속 불가
- 다수의 인스턴스가 연결된 형태: Prototype Chain
27. 검색 우선순위
28. 함수 즉시 실행
함수 즉시 실행이란?
- 엔진이 함수 코드를 만나면 자동으로 함수를 실행하는 행태
29. 클로저
클로저 개요
- 자바스크립트의 특정 기능을 지칭
- function 오브젝트를 생성할 때 [[Scope]]에 렉시컬 환경을 설정하고
함수가 호출되었을 때 [[Scope]]의 프로퍼티를 사용하는 메커니즘
- function 오브젝트 생성 과정을 히해하면 클로저는 단지 논리적인 접근.