5. null과 undefined
- 값이 없는 겨우
- null : 개발자가 명시적으로 없다고 지정
- undefined : 변수에 값이 지정 안 됨 (메모리 주소 지정 x), 해당 데이터가 없을때, return문이 없는 함수
- ★(주의) typeof null = object -> js 자체 버그임
6. 실행컨텍스트 및 콜 스택 소개
- 실행컨텍스트 (스코프, 변수, 객체, 호이스팅)
: 실행할 코드에 제공할 환경정보를 모아놓은 객체 (개발자가 작성한)
(1) 선언된 변수를 위로 끌어올림 = 호이스팅
(2) 외부 환경 정보 구성
(3) this 값 설정
- 스택 (stack) : 바스켓 같음 (LIFO : last in first out)
- 큐 (queue) : 원형 (FIFO : first in first out)
- 콜 스택 : 맨 위에 쌓이는 (노출되는) 순간 : 현재 코드에 관여하게 되는 시점이다.
7. record와 호이스팅1 (실행컨텍스트)
- 실행 컨텍스트 객체의 실체 (= 담기는 정보)
(1) variableEnvironment : 현재 컨텍스트 내의 식별자 정보(=record) + 외부환경정보(=outer)
(2) LexcialEnvironment : variableEnvironment 동일 && 변경사항을 실시간으로 반영
(3) ThisBinding : this 식별자가 바라봐야할 객체
* variableEnvironment (VE) / LexcialEnvironment (LE)
- VE : 스냅샷 유지o (실시간 변동x)
- LE : 스냅샷 유지 x (실시간 변동사항 반영)
=> 실행 컨텍스트를 생성할때, VE에 정보 먼저 담고 -> 복사 -> LE를 이후에 활요함
** Record ( 현재 컨텍스트 내의 식별자 정보 ) + 호이스팅
- 식별자정보를 컨텍스트에 기록한다
- 수집 대상 정보 : 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자 등
- 수집이 된다 = 호이스팅이 된다 (순서대로 수집 ! 실행 x)
** 호이스팅 (레코드와 관련됨: 식별자 개념을 수집할 때 호이스팅 발생)
- 가상개념임
- hoist : 끌어올리다 / 식별자 정보를 맨 위로 끌어올림 (레코드를 수집하는 과정임)
- 규칙 : 매개변수&변수는 선언부를 호이스팅함 / 함수는 위로 끌어올려졌다 (모든 함수x)
8. record와 호이스팅2 (함수의 호이스팅)
- 함수선언문 : 함수의 정의부만 존재 (할당 명령 x)
- 함수표현식 : 별도의 변수에 함수를 할당함 (익명함수 / 기명함수 : 함수의 이름을 적는 것: 활용성 낮음)
* LE = > 레코드의 수집과정= 호이스팅
* 함수선언문 : 함수 전체가 위로 호이스팅
* 함수표현식 : 변수만 위로 호이스팅
** 주의할 점
( 함수선언문 ) 전체가 호이스팅 되서 전체가 영향을 줌
( 함수 표현식)은 변수만 위로 올려쓰니 이걸 습관화해서 사용해야함!!
9. outerEnvironmentReference (외부환경)
- 스코프 : 식별자에 대한 유효범위
- 스코프 체인
: outer는 현재 호출된 선언당시(★)
: LE를 참조하고 있음 (전 단계의 LE를 다음단계의 outer로 참조하고 있다)
* [정리]
각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고있고
그 실행 컨텍스트가 선언될 당시에 LE정보가 다 들어있으니
스코프 체인에 의해 상위 컨텍스트의 레코드를 읽기 가능
10. this (전역공간 this / 함수this / 메서드 this)
- 객체 지향 언어 (클래스로 생성한 인스턴스) / JS는 어디에서나 다양하게 사용가능
- 실행 컨텍스트 ( 실행할 코드에 제공할 환경정보를 모아놓은 객체)의 3가지 중 1개
- 실행 컨텍스트가 생성될 때 결정됨,
- 전역공간 : this = 전역공간
: 런타임(코드가 돌아가는 환경) : 브라우저 : window 객체 / node : global 객체
* 비교
메서드 (종속되어 호출되어 사용 ) : 객체.메서드명();--객체에 대한 동작 수행 / 호출의 주체 = this = 객체
함수 ( 독립적으로 사용 가능) : 함수명(); / 호출의 주체 없음 (this= 전역객체)
// this
let obj={
methodA : function() {console.log(this)},
inner : {
methodB : function() {console.log(this)},
}
};
obj.methodA() ; //this === obj
obj['methodA']; //this === obj
obj.inner.methodB(); // this === obj.inner
obj.inner['methodB'](); // this === obj.inner
obj.['inner'].methodB(); // this === obj.inner
obj.['inner'].['methodB'](); // this === obj.inner
* 함수로서 호출할때 : 호출 주체 x --> 전역객체 의미함
11. this 우회방법 ( 콜백함수 this / 생성자 함수 this)
- this를 변수에 저장하고 콘솔을 변수를 찍어서 확인
- 화살표 함수 (= this를 바인딩하지 않은 함수)
: 함수내부에서 this가 전역객체를 바라보는 문제(this유실) 때문에 도입됨
★ 화살표함수 & 일반함수의 큰 차이점은 : this binding 여부
* 콜백함수 호출시 그 함수 내부에서의 this
--> 무조건 전역객체를 바라보게 되어있음 (윈도우 객체 / 글로벌 객체)
--> (예외: 콜백함수에 this를 지정한 경우 )
: 콜백함수도 함수임 (매개변수로 들어가는 함수)
(1) 별도지정없음 : 전역객체
- setTimeout (function() {~~};
- function(x){~~};
(2) addListener 안에서의 this : 항상 호출한 주체의 element를 return
- function(e) {~~};
* 생성자 함수 내부에서의 this
- 생성자 : 구체적인 인스턴스(지금은 객체로 이해)를 만들기 위한 틀
- 새로운 인스턴스를 만들때마다 this가 달라짐
12. 명시적 this 바인딩 및 유사배열객체
- call, apply, bind 메서드
(1) call
- this를 잃어버려 전역객체를 바라보는 상황
let func = function(a,b,c) {
console.log(this,a,b,c);
}
//no binding
func(1,2,3); //global(~~) , a,b,c
//명시적 바인딩
//func.call({})
func({x:1},1,2,3); // {x:1} 4 5 6
//객체도 명시적바인딩 가능
let obj = {
a:1 ,
method: function(x,y){
console.log(this.a, x,y);
}
}
//method 함수 안의 this는 항상 obj
obj.method(2,3); //1,2,3
//명시적바인딩
obj.method({a:4},5,6); //4,5,6
(2) apply
- call과 유사기능
- 뒤에 있는 매개변수를 대괄호로 묶어줘야함
let func = function(a,b,c) {
console.log(this,a,b,c);
}
//명시적 바인딩-- apply
//func.call({})
func.apply({x:1},1,2,3); // {x:1} 4 5 6
//객체도 명시적바인딩 가능
let obj = {
a:1 ,
method: function(x,y){
console.log(this.a, x,y);
}
}
//method 함수 안의 this는 항상 obj
obj.method(2,3); //1,2,3
//명시적바인딩
obj.method({a:4},[5,6]); //4,5,6
(3) 유사배열객체
- 배열 (index, length)처럼 length가 필수 + index의 번호가 0부터 증가해야함
- ES6 ( Array,from)으로 쉽게 객체-> 배열 변환 가능
//유사배열객체
//인덱스 0부터, length까지 가지고 있는 배열
//배열처럼 배열의 메서드는 못씀 (obj.push이런거 사용 불가능-> 유사하게 사용)
let obj ={
0: 'a'
1: 'b'
2: 'c'
length: 3
};
Array.prototype.push.call(obj,'d');
console.log(obj); // {0:'a',1:'b',2:'c',3:'d', length:4}
//ES6 (Array.from 메서드 등장)
//객체->배열 변환
let arrr = Array.from(obj);
13. Call | Apply | Bind 응용
(1) call
-중복되는 구간을 새로 만들어서 call사용하는 시점에 this 바인딩하
function Person(name,gender){
this.name = name;
this.gender = gender;
}
function Student(name,gender,school) {
Person.call(this, name, gender);
//this.name = name;
//this.gender = gender;
this.school = school;
}
function Employee(name,gender,school) {
Employee.call(this, name, gender);
//this.name = name;
//this.gender = gender;
this.company = company;
}
var kd = new Student('길동','male','서울대');
var kd = new Student('길순','female','삼성');
(2) Apply
- Math.max.apply(null, 배열);
- spread operator
//1.
//비효율적인 최댓값,최솟값 찾기
let number = [10,20,3,16,45];
let max = (min =number[0]); //10
number.forEach(function (number){
//현재 돌아가는 숫자가 max보다 큰 경우
if(number > max) { max = number;}
if(number < min ) { min = number;}
}
console.log( max, min);
//2.
//apply-> (this로 엮을 객체, 배열)
//apply-> ({},[]);
var numbers = [10,20,3,16,45];
//Math.max(1,2,3) -> apply를 사용하고 this는 null넣어줌, 그리고 배열 가져오기
let max = Math.max.apply(null, numbers);
let min = Math.min.apply(null, numbers);
//3.
//스프레드 오퍼레이터
let max = Math.max(...numbers);
let min = Math.min(...numbers);
(3) Bind
//bind 메서드
// ->this를 바인딩하는 메서드
//call, apply랑 좀 다름 -> 즉시 호출하는 call,apply와 다름
//bind는 해당하는 함수를 새로운 함수를 return해서 저장 후 사용
//목적
//1. 함수에 this를 '미리' 적용
//2. 부분 적용 함수!
let func = function(a,b,c,d){
console.log(this, a,b,c,d);
}
func(1,2,3,4); // global 객체, 1,2,3,4
//목적1
//함수에 this를 미리 적용!
//새로운 함수의 return값을 받아야해서 변수에 넣기
let bindFunc1 = func.bind({x:1}); //새로운 함수 + this값은 1로 고정
bindFunc1(5,6,7,8); // {x:1} 5 6 7 8
//목적2
//부분 적용 함수!
let bindFunc1 = func.bind({x:1}, 4,5); //뒤에4,5를 미리 선점하기
bindFunc2(6,7); // 원래 4개 인자 필요한데, 2개 인자만 넣으면 됨 //{x:1} 4 5 6 7
// name 프로퍼티!
// 'bound'라는 접두어 - bind의 수동태(바인드가 되었다)
// 추적하기 쉬움
console.log(func.name); // func
console.log(bindFunc1.name); // bound func
console.log(bindFunc2.name); // bound func
** 화살표함수는 this를 바인딩하는 과정이 없음
끝.
[출처]
1. 스파르타 코딩, JavaScript 문법 종합반 3주차 (5강-13강)
'JavaScript' 카테고리의 다른 글
JS 5주차 정리 :: DOM | 클래스 | getters setters 개념 | 클래스 상속 | 클로저 (0) | 2023.10.17 |
---|---|
JS 4주차 정리 :: 콜백함수 | 동기 & 비동기 | promise | 제네레이터 및 | async await (2) | 2023.10.17 |
JS 3주차 정리 :: 메모리 | 데이터 할당 | 불변객체 (얕은복사 & 깊은복사) (1) | 2023.10.13 |
JS 2주차 정리 :: ES6 문법 8가지 (구조분해할당, ...전개구문) | 일급객체 | Map | Set (1) | 2023.10.13 |
JS 1주차 정리 :: 데이터 타입 | 형 변환 | 화살표 함수 | 조건문 | 반복문 | 객체 | 배열 (0) | 2023.10.12 |