-
Notifications
You must be signed in to change notification settings - Fork 2
[정리] 2주차, 12~19
1. 함수
2. 스코프
3. 전역 변수의 문제점
4. let,const 키워드와 블록 레벨 스코프
5. 프로퍼티 어트리뷰트
6. 생성자 함수에 의한 객체 생성
7. 함수와 일급 객체
8. 프로토타입
-
함수
: 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것, 객체 타입의 값으로 평가❗️특이점 : 일반
객체
는 호출이 불가능하지만,함수
는 호출 가능 -
함수
정의 방식 4가지
- 함수 선언문
function add(x,y) {
return x+y;
}
- 함수 표현식
var add = function(x,y) {
return x+y;
}
- 생성자 함수
var add = new Function('x','y','return x+y');
- 화살표 함수 (ES6)
var add = (x,y) => x+y;
-
함수 선언문과 함수표현식 차이.
=> 함수 생성 시점이 다르다.
선언문 -> 호이스팅 일어나서 런타임 이전에 생성.
표현식 -> 런타임때 생성 -
매개변수와 인수
인수는 arguments 객체에 정보를 담는다.
인수 체크 & 초기화를 통해서 기본값 설정(undefined) -
값 전달
원시값 -> 값에 의한 전달
객체 -> 참조에 의한 전달
참조에 의한 전달을 통해서 함수 외부의 상태를 변경하게 된다. -
함수의 여러 형태
순수 함수 : 외부 상태를 변경하지 않고, 외부 상태에 의존하지 않는 함수
콜백함수 : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수. 비동기 처리에 자주 사용됨
-
스코프
는식별자를 검색하는 규칙
식별자는 유일해야 하는데 같은 이름의 변수를 사용가능한 것은 스코프를 통해 충돌을 방지하기 때문.
스코프
= 네임스페이스- 전역 스코프 : 코드의 가장 바깥 영역
- 지역 스코프 : 함수 몸체 내부
스코프 체인
: 모든 스코프는 하나의 계층적 구조로 연결되며, 식별자를 인식,검색하는 일련의 과정. 모든 지역스코프의 최상위 스코프는 전역스코프
-
블록 레벨 스코프 : 함수뿐 아니라 모든 코드 블록이 지역 스코프를 만듬
-
함수 레벨 스코프 :
var
키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 만듬 -
동적 스코프 : 함수를 어디서 호출하는지에 의해 결정.
-
정적 스코프 (렉시컬 스코프) : 함수를 어디서 정의했는지에 의해 결정.
자바스크립트
는 여기에 해당
-
생명주기 : 생성되고 소멸되는 주기.
-
전역 변수의 문제점
- 암묵적 결합 허용 (전역변수를 참조, 사용, 변경을 할 수 있다)
- 긴 생명주기 (메모리 리소스 사용, 변경할 수 있는 시간,기회가 많아짐)
- 전역 변수의 검색속도가 상대적으로 느림
- 네임스페이스 오염 (변수 중복 가능성을 높임)
-
전역 변수 억제 방법
- 즉시 실행 함수 : ( ... )로 함수를 만들기. (라이브러리로 만들때 많이 씀)
- 네임스페이스 객체 : 전역 객체에 변수를 프로퍼티로 추가.
- 모듈 패턴 사용 : 반환하는 객체에 메서드, 프로퍼티를 추가.
- ES6 모듈 : 파일 자체의 독자적인 모듈 스코프를 사용.
IIFE(Immediately Invoked Function Expression)은 함수를 실행하는 구문이 없어도 바로 함수가 실행되는 함수 표현식을 말한다.
특징
- 함수의 블록 영역 특징 때문에 전역을 오염시키지 않는다.
- 함수 호출 구문 없이도 실행된다.
- 전역 영역에서 침범이 불가능한 함수 영역을 갖고 있기 때문에 보안 처리가 가능하다.
(function() { console.log('쇼미더머니!') })();
IIFE 패턴은 스스로 실행되는 무명 함수(Self-Executing Anonymous Function)로 알려진 디자인 (설계) 패턴이며, 크게 두 부분으로 구성된다.
- 괄호((), Grouping Operator그룹 연산자)로 둘러싸인 무명함수이다. 이는 전역범위를 오염시키는 것 뿐만아니라 IIFE 내부의 변수에 접근하는 것을 방지(캡슐화)한다.
- 즉시 실행 함수를 실행하는 괄호(())이다. 이를 통해 JS엔진은 함수를 즉시 실행한다. IIFE를 변수에 할당하면 IIFE 자체는 저장이 되지 않고 함수가 실행된 결과(return 값)만 저장한다.
웹에서 JS는 언제든 변수의 값이 수정 될 수 있다. 그렇게 되면 프로그램이 망가질 확률이 크다.(망가질 확률이 적은 것이 좋은 프로그래밍이다) 즉, 프로그래밍한 코드를 보호하기 위해 IIFE 패턴을 사용한다.
-
var
키워드
- 변수 중복 선언 허용
- 함수 레벨 스코프
- 변수 호이스팅
-> 선언 단계, 초기화 단계. 이때에는 undefined
할당 단계.
-
let
키워드
- 변수 중복 선언 x
- 블록 레벨 스코프
- 변수 호이스팅 x
-> 선언단계.
일시적 사각지대. 이때에는 ReferenceError
초기화 단계.
할당 단계.
let
으로 선언한 전역 변수는 전역 객체의 프로퍼티에 추가되지 않음.
-
const
키워드- 선언과 초기화 동시에
- 재할당 금지
- 상수
*const
키워드로 객체를 할당해서 객체를 변경 가능
. 이유는 객체를 가리키는 값이 바뀌는게 아니기 때문.
JS는 var, function 선언문을 사용할 경우, 브라우저가 해석하는 과정에서 영역 최상위로 끌어올리는 현상을 보이는데 이것을 호이스트라고 한다.
끌어올려지는 것이 아닌 정확히 말하면 "메모리에 등록이 된다"가 맞는 말이다.
변수는 원래 먼저 선언이 되어 있어야 하는데 만약 없으면 오류를 유발한다. 하지만 자바스크립트는 선언된 변수가 없다면 영역 내의 선언된 다른 변수를 상위로 끌어올리려고 한다.
중요하다기보다는 너무 심화적으로 파고들 필요가 없어 보여서 패스.
-
Object
생성자 함수
- new 키워드 사용.
-
Object
,String
,Number
,Boolean
,Function
,Array
,Date
,RexExp
,Promise
등등..
- 생성자 함수
- 객체 리터럴의 문제점 : 직관적이고 간편하지만, 생성해야할 갯수가 많아지면 불편
- 생성자 함수 => 클래스처럼 사용가능, 여러개 만들기 편함
함수호출방식 |
this 가리키는 값 |
---|---|
일반 함수로서 호출 | 전역 객체 |
메서드로서 호출 | 메서드를 호출한 객체 |
생성자 함수로서 호출 | 생성자 함수가 생성한 객체 |
- 생성자 함수 인스턴스 생성 과정
- 인스턴스 생성 -> 프로퍼티 추가 및 초기값 할당 // 반환은 자바스크립트 엔진에서 암묵적으로 실행
- this 바인딩은 런타임 이전에 실행
- Callable 과 Constructor
- 모든 함수는 호출할 수 있는 프로퍼티가 생성 (callable)
- 생성자 함수로 호출 할 수 있는 함수인지 확인. // Constructor vs non-Constructor
- Constructor vs non-Constructor 구분
- Constructor : 함수 선언문, 함수 표현식, 클래스
- Non-Constructor : 메서드(ES6 축약표현), 화살표 함수
-
new.target
으로new
연산자를 사용했는지 체크가능
- 재귀 형식으로 생성자 함수 호출 가능.
- 스코프 세이프 생성자 패턴도 가능
-
Object
,Function
:new
연산자로 생성하는 것과 상관없이 동일한 결과 나옴 -
String
,Number
,Boolean
:new
연산자로 생성하는 것과 결과가 다르게 나옴.
-
일급 객체
: 다음 조건을 만족하는 것을일급객체
라고 부른다- 무명의 리터럴 생성할 수 있다. 런타임에 생성 가능
- 변수, 자료구조에 저장 가능.
- 함수의 매개변수 전달 가능.
- 함수의 반환값 사용 가능.
-
Arguments
프로퍼티- 매개변수 인자 정보를 가짐. 가변인자 함수 구현에 유용
-
length
프로퍼티- 매개변수 개수의 정보를 가짐
-
name
프로퍼티- 객체를 가리키는 식별자 이름 (ES6) // ES5는 빈문자열
-
prototype
프로퍼티- 생성자 함수로 호출 할 수 있는 객체.
-
객체
: 상태데이터 + 동작 - 상속 : 어떤 객체의 프로퍼티나 메서드를 다른 객체가 그대로 사용할 수 있는 것. 자바스크립트는 프로토타입 기반 상속
-
Object.prototype
은 모든 객체의 프로토타입이다. -
__proto__
접근자를 사용하는 이유 : 상호 참조를 방지하려고.
구분 | 소유 | 값 | 사용주체 | 사용목적 |
---|---|---|---|---|
__proto__ 접근자 프로퍼티 |
모든 객체 | 프로토타입의 참조 | 모든 객체 | 객체가 자신의 프로토타입에 접근 또는 교체하기 위해 사용 |
prototype 프로퍼티 |
Constructor |
프로토타입의 참조 | 생성자 함수 | 생성자 함수가 자신이 생성할 객체의 프로토타입을 할당하기 위해 사용 |
-
프로토타입의 생성 시점
- 생성자 함수와 프로토 타입은 쌍으로 존재하기 때문에 생성된 시점은 동일.
- 빌트인 생성자 함수는 전역 객체 생성 시점.
-
프로토타입 체인
- 자바스크립트가 객체 지향 프로그래밍의 상속을 구현하는 매커니즘
- 해당 객체의 프로퍼티가 없으면 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색
-
프로토타입 교체
- 생성자 함수의
prototype
프로퍼티를 통해 프로토 타입 교체 :Constructor
가 사라짐. 생성자 함수가 교체된 프로토타입을 가리킴. - 인스턴스에 의한 프로토타입 교체 : 객체의
__proto__
접근자를 통해 변경. 생성자 함수가 교체된 프로토타입을 가리키지 않음.
- 생성자 함수의
-
직접 상속
-
Object.create
에 의한 직접 상속.
장점-
new
연산자 없이 객체 생성 - 프로토타입 지정하면서 객체 생성
- 객체 리터럴에 의해 생성된 객체도 상속
-
- 객체 리터럴 내부에서
__proto__
에 의한 직접 상속
-
-
정적 프로퍼티 / 메서드 추가 방법
- 생성자 함수에 직접 프로퍼티, 메서드를 추가하면 정적으로 됨. 인스턴스는 사용하지 못함.
- 가장 간단한 변수 영역은 소스 코드 상의 모든 곳에서 사용할 수 있는 전역 변수.
- 전역 변수는 많은 언어에서 나쁜 관습으로 취급 되지만, 그런 경우에도 함수 명이나 클래스 명은 대부분 전역에서 접근할 수 있다.
var phone = "Galaxy";
console.log("전역 변수", phone); // 'Galaxy'
function scopeFn() {
var phone = "iPhone";
console.log("지역 변수", phone); // 'iPhone'
}
- 대부분의 프로그래밍 언어와 달리 JavaScript는 함수 안에서만 유효한 지역 변수를 제
- 함수 영역에서 사용 되는 지역 변수는 함수가 반환되면 더 이상 사용할 수 없다.
- 함수 영역 밖에서는 접근이 불가능!!! (보호된다)
- 블록 문 내부에 선언된 변수는 블록 영역에서만 접근 가능.
- ES5에서는 블록 영역을 지원하지 않지만 ECMAScript 2015(ES6, 표준이 되는 문서)에서 수 있다.
- ES5에서는 function을 제외한 모든 문은 전부 블록 문이 만들어지지 않는다.
- ES6에서 부터는 let 키워드 지원하는데 let을 사용하면 해당 문은 블록 영역을 지정해 줄 수 있다.