데이터 타입 심화
- 데이터 타입의 종류
💡 [기본형과 참조형의 구분 기준] => 값의 저장방식, 불변성 여부
- 복제의 방식
- 기본형 : 값이 담긴 주소값을 바로 복제
- 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제
- 불변성의 여부
- 기본형 : 불변성을 띔
- 참조형 : 불변성을 띄지 않음
- 메모리와 데이터
- 비트
- 컴퓨터가 이해할 수 있는 가장 작은 단위
- 0과 1을 가지고 있는 메모리를 구성하기 위한 작은 조각
- 바이트
- 메모리 : byte 단위로 구성
- 모든 데이터는 byte 단위의 식별자인 메모리 주소값으로 서로 구분
- 만일, 64비트(8바이트) 정수는 메모리에 어떻게 저장? => 64비트를 8개의 바이트로 분할하고, 각 바이트를 메모리에 저장, 따라서 64비트 정수는 메모리에서 8개의 연속된 바이트에 저장
- java, c와 다른 javascript의 메모리 관리 방식(feat. 정수형)
- 8을 저장하는 방법
- JS : let a = 8(8byte)
- JAVA
- byte a = 8(1byte)
- short a = 8(2byte)
- int a = 8(4byte)
- long a = 8(16byte)
- 식별자, 변수
var testValue = 3
변수 = 데이터
식별자 = 변수명
- 변수 선언과 데이터 할당
- 할당 예시
/** 선언과 할당을 풀어 쓴 방식 */
var str;
str = 'test!';
/** 선언과 할당을 붙여 쓴 방식 */
var str = 'test!';
- 값을 바로 변수에 대입하지 않는 이유
- 자유로운 데이터 변환
- 이미 입력한 문자열이 길어진다면?
- 숫자는 항상 8byte로 고정이지만, 문자는 고정x(영문 : 1byte, 한글 : 2byte). 그래서, 이미 주소에 할당된 데이터를 변환하려 할 때 훨씬 더 큰 데이터를 저장하려 한다면 → 이후부터 저장되어있는 모든 데이터를 다 미뤄야함.
- 메모리의 효율적 관리
- 똑같은 데이터를 여러번 저장해야 한다면?
- 1만개의 변수를 생성해서 모든 변수에 숫자 1을 할당하는 상황을 가정
- 모든 변수를 별개로 인식한다고 한다면, 1만개의 변수 공간을 확보
- 바로 대입하는 case) 숫자형은 8 바이트 고정이죠
- 1만개 * 8byte = 8만 byte
- 변수 영역에 별도 저장 case)
- 변수 영역 : 2바이트 1만개 = 2만바이트 (변수 영역에 저장되는 데이터는 2바이트로 가정)
- 데이터 영역 : 8바이트 1개 = 8바이트
- 총 : 2만 8바이트
- 바로 대입하는 case) 숫자형은 8 바이트 고정이죠
- 기본형 데이터와 참조형 데이터
- 변수 vs 상수
- 변수: 변수 영역 메모리 변경 o
- 상수: 변수 영역 메모리 변경 x
- 불변 vs 불변x
- 불변: 데이터 영역 메모리 변경 x
- 불변x : 데이터 영역 메모리 변경 o
가변값과 가변성(참조형 데이터)
- 참조형 데이터의 변수 할당 과정
// 참조형 데이터는 별도 저장공간(obj1을 위한 별도 공간)이 필요합니다!
var obj1 = {
a: 1,
b: 'bbb,
};
실행컨텍스트(스코프, 변수, 객체, 호이스팅)
- 실행 컨텍스트: 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
- 스택 vs 큐
- 콜 스택(call stack)
: 실행 컨텍스트 즉, 동일 환경에 있는 코드를 실행할 때 필요한 환경 정보들을 모아 놓은 객체를 '스택'의 한 종류인 콜스택에 쌓아 올림. 가장 위에 쌓여있는 컨텍스트와 관련된 코드를 실행하는 방법으로 코드의 환경 및 순서를 보장
- 컨텍스트의 구성
- 구성방법
- 전역공간
- eval()함수
- 함수(우리가 흔히 실행컨텍스트를 구성하는 방법)
- 실행컨텍스트 구성 예시 코드
// ---- 1번 var a = 1; function outer() { function inner() { console.log(a); //undefined var a = 3; } inner(); // ---- 2번 console.log(a); } outer(); // ---- 3번 console.log(a);
- 실행컨텍스트 구성 순서
코드실행 → 전역(in) → 전역(중단) + outer(in) → outer(중단) + inner(in) → inner(out) + outer(재개) → outer(out) + 전역(재개) → 전역(out) → 코드종료 - 특정 실행 컨텍스트가 생성되는(또는 활성화되는) 시점이 콜 스택의 맨 위에 쌓이는(노출되는) 순간을 의미
곧, 현재 실행할 코드에 해당 실행 컨텍스트가 관여하게 되는 시점을 의미
- 구성방법
- 실행 컨텍스트 객체의 실체(=담기는 정보)
- VariableEnvironment
- 현재 컨텍스트 내의 식별자 정보(=record)를 가짐
- var a = 3
- 위의 경우, var a를 의미
- 외부 환경 정보(=outer)를 가짐
- 선언 시점 LexicalEnvironment의 snapshot
- 현재 컨텍스트 내의 식별자 정보(=record)를 가짐
- LexicalEnvironment
- VariableEnvironment와 동일하지만, 변경사항을 실시간으로 반영
- ThisBinding
- this 식별자가 바라봐야할 객체
- VariableEnvironment, LexicalEnvironment의 개요
- VE vs LE => 담기는 항목 동일
- VE : 스냅샷을 유지
- LE : 스냅샷을 유지x 즉, 실시간으로 변경사항을 계속해서 반영
=> 실행 컨텍스트 생성할 때, VE에 정보 먼저 담고, 복사하여 LE를 생성, 그 이후 LE활용
- 구성요소(VE, LE 동일)
- environmentRecord(=record)
- 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장
- 함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자 등
- outerEnvironmentReference(=outer)
- LexicalEnvironment - environmentRecord(=record)와 호이스팅
- 개요
- 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장(수집)
- 수집 대상 정보 : 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자 등
- 컨텍스트 내부를 처음부터 끝까지 순서대로 훑어가며 수집
- 호이스팅 => record 수집 과정
- 변수정보 수집을 모두 마쳤더라도 아직 실행 컨텍스트가 관여할 코드는 실행 전의 상태(JS 엔진은 코드 실행 전 이미 모든 변수정보를 알고 있는 것)
- 변수 정보 수집 과정을 이해하기 쉽게 설명한 ‘가상 개념’
- 호이스팅 규칙
- 호이스팅 법칙 1 : 매개변수 및 변수는 선언부를 호이스팅
<적용 전>
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기
function a (x) {
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
<매개변수 적용>
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기
function a () {
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
<호이스팅 적용>
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기
function a () {
var x;
var x;
var x;
x = 1;
console.log(x);
console.log(x);
x = 2;
console.log(x);
}
a(1);
- 예상: 1 → undined → 2
- 실제: 1 → 1 → 2
- 호이스팅 법칙 2 : 함수 선언은 전체를 호이스팅
<적용 전>
//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기
function a () {
console.log(b);
var b = 'bbb';
console.log(b);
function b() { }
console.log(b);
}
a();
<호이스팅 적용>
//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기
function a () {
var b; // 변수 선언부 호이스팅
function b() { } // 함수 선언은 전체를 호이스팅
console.log(b);
b = 'bbb'; // 변수의 할당부는 원래 자리에
console.log(b);
console.log(b);
}
a();
- 예상: 에러(또는 undefined) → ‘bbb’ → b함수
- 실제: b함수 → ‘bbb’ → ‘bbb’
* 주의할 점
- 함수 정의 방식 => 함수 표현식을 활용하는 습관을 들이자!
함수 선언문을 이용한 코드는 함수 전체가 위로 올라오고,
함수 표현식을 이용한 코드는 함수 선언부만 위로 올라오므로 그 이후의 코드만 영향 받음!
// 함수 선언문. 함수명 a가 곧 변수명
// function 정의부만 존재, 할당 명령이 없는 경우
function a () { /* ... */ }
a(); // 실행 ok
// 함수 표현식. 정의한 function을 별도 변수에 할당하는 경우
// (1) 익명함수표현식 : 변수명 b가 곧 변수명(일반적 case에요)
var b = function () { /* ... */ }
b(); // 실행 ok
// (2) 기명 함수 표현식 : 변수명은 c, 함수명은 d
// d()는 c() 안에서 재귀적으로 호출될 때만 사용 가능하므로 사용성에 대한 의문
var c = function d () { /* ... */ }
c(); // 실행 ok
d(); // 에러!
<호이스팅 적용>
// 함수 선언문은 전체를 hoisting
function sum (a, b) { // 함수 선언문 sum
return a + b;
}
// 변수는 선언부만 hoisting
var multiply;
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) { // 변수의 할당부는 원래 자리
return a + b;
};
- LexicalEnvironment - 스코프, 스코프 체인, outerEnvironmentReference(=outer)
- 주요 용어
- 스코프
- 식별자에 대한 유효범위를 의미해요
- 대부분 언어에서 존재하구요, 당연하게도 JS에서도 존재하죠
- 스코프 체인
- 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것
3. outerEnvironmentReference(이하 outer) : 스코프 체인이 가능토록 하는 것(외부 환경의 참조정보)
- 스코프 체인
- outer는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조(그 당시의 환경 정보를 저장)
- 예를 들어, A함수 내부에 B함수 선언 → B함수 내부에 C함수 선언(Linked List)한 경우
- 결국 타고, 타고 올라가다 보면 전역 컨텍스트의 LexicalEnvironment를 참조하게 됩니다.
- 항상 outer는 오직 자신이 선언된 시점의 LexicalEnvironment를 참조하고 있으므로, 가장 가까운 요소부터 차례대로 접근 가능
- 결론 : 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에게만 접근이 가능
var a = 1;
var outer = function() {
var inner = function() {
console.log(a); //a=undefined => 호이스팅에 의해 var a, console.log(a), a=3이 됨
var a = 3;
};
inner();
console.log(a); // a=1 => inner는 이미 사라져서 참조x, 전역영역에서는 참조 가능
};
outer();
console.log(a); // a=1
각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고, outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE정보가 다 들어있으니 scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.
this(정의, 활용방법, 바인딩, call, apply, bind)
- 상황에 따라 달라지는 this
- this는 실행 컨텍스트가 생성될 때 결정 => this는 함수를 호출할 때 결정
- 전역 공간에서의 this
- 전역 공간에서 this는 전역 객체를 가리켜요.
- 런타임 환경에 따라 this는 window(브라우저 환경) 또는 global(node 환경)를 각각 가리킵니다.
런타임 환경: javascript로 만들어놓은 프로그램이 구동중인 환경
//브라우저 환경 this 확인
console.log(this);
console.log(window);
console.log(this === window);
//node 환경 this 확인
console.log(this);
console.log(global);
console.log(this === global);
- 메서드로서 호출할 때 그 메서드 내부에서의 this
함수: 그 잧체로 독립적인 기능 수행
함수명();
메서드: 자신을 호출한 대상 객체에 대한 동작 수행
객체.메서드명();
- this의 할당
// CASE1 : 함수
// 호출 주체를 명시할 수 없기 때문에 this는 전역 객체를 의미
var func = function (x) {
console.log(this, x);
};
func(1); // Window { ... } 1
// CASE2 : 메서드
// 호출 주체를 명시할 수 있기 때문에 this는 해당 객체(obj)를 의미
// obj는 곧 { method: f }를 의미하죠?
var obj = {
method: func,
};
obj.method(2); // { method: f } 2
- 함수로서의 호출과 메서드로서의 호출 구분 기준 : . []
- 메서드 내부에서의 this => this에는 호출을 누가 했는지에 대한 정보가 담김
var 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
- 함수로서 호출할 때 그 함수 내부에서의 this
- 함수 내부에서의 this
- 어떤 함수를 함수로서 호출할 경우, this는 지정x(호출 주체가 알 수 x)
- 실행컨텍스트를 활성화할 당시 this가 지정되지 않은 경우, this는 전역 객체를 의미
- 따라서, 함수로서 ‘독립적으로’ 호출할 때는 this는 항상 전역객체를 가리킨다
- 메서드 내부함수의 this: 메서드의 내부라고 해도, 함수로서 호출한다면 this는 전역 객체를 의미
var obj1 = {
outer: function() {
console.log(this); // (1)
var innerFunc = function() {
console.log(this); // (2), (3)
}
innerFunc();
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod();
}
};
obj1.outer();
- 실행결과: (1) : obj1, (2) : 전역객체, (3) : obj2
- 메서드의 내부 함수에서의 this 우회
- 변수를 활용하는 방법: 내부 스코프에 이미 존재하는 this를 별도의 변수(ex : self)에 할당하는 방법
var obj1 = {
outer: function() {
console.log(this); // (1) outer
// AS-IS
var innerFunc1 = function() {
console.log(this); // (2) 전역객체
}
innerFunc1();
// TO-BE
var self = this;
var innerFunc2 = function() {
console.log(self); // (3) outer
};
innerFunc2();
}
};
// 메서드 호출 부분
obj1.outer();
2. 화살표 함수(=this를 바인딩하지 않는 함수): 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다!
일반 함수와 화살표 함수의 가장 큰 차이점은 무엇인가요?
> this binding 여부가 가장 적절한 답
var obj = {
outer: function() {
console.log(this); // (1) obj
var innerFunc = () => {
console.log(this); // (2) obj
};
innerFunc();
}
}
obj.outer();
- 콜백 함수 호출 시 그 함수 내부에서의 this
: 콜백 함수도 함수기 때문에 this는 전역 객체를 참조, 하지만 콜백함수를 넘겨받은 함수에서 콜백 함수에 별도로 this를 지정한 경우는 예외, 즉 콜백함수 내부의 this는 해당 콜백함수를 넘겨받은 함수(메서드)가 정한 규칙에 따라 값이 결정
// 별도 지정 없음 : 전역객체
setTimeout(function () { console.log(this) }, 300);
// 별도 지정 없음 : 전역객체
[1, 2, 3, 4, 5].forEach(function(x) {
console.log(this, x);
});
// addListener 안에서의 this는 항상 호출한 주체의 element를 return하도록 설계되었음
// 따라서 this는 button을 의미함
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
console.log(this, e);
});
- setTimeout 함수, forEach 메서드는 콜백 함수를 호출할 때 대상이 될 this를 지정하지 않으므로, this는 곧 window객체
- addEventListner 메서드는 콜백 함수 호출 시, 자신의 this를 상속하므로, this는 addEventListner의 앞부분(button 태그)
- 생성자 함수 내부에서의 this
* 생성자 : 구체적인 인스턴스(어려우면 객체로 이해!)를 만들기 위한 일종의 틀
var Cat = function (name, age) {
this.bark = '야옹';
this.name = name;
this.age = age;
};
var choco = new Cat('초코', 7); //this : choco
var nabi = new Cat('나비', 5); //this : nabi
- 명시적 this 바인딩 : 자동으로 부여되는 상황별 this의 규칙을 깨고 this에 별도의 값을 저장
- call 메서드
- 호출 주체인 함수를 즉시 실행하는 명령어
- call명령어를 사용하여, 첫 번째 매개변수에 this로 binding할 객체를 넣어주면 명시적으로 binding할 수 o
var func = function (a, b, c) {
console.log(this, a, b, c);
};
// no binding
func(1, 2, 3); // Window{ ... } 1 2 3
// 명시적 binding
// func 안에 this에는 {x: 1}이 binding돼요
func.call({ x: 1 }, 4, 5, 6}; // { x: 1 } 4 5 6
// 예상되는 this가 있음에도 일부러 바꾸는 연습
var obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
}
};
obj.method(2, 3); // 1 2 3
obj.method.call({ a: 4 }, 5, 6); // 4 5 6
- apply 메서드
- call 메서드와 완전히 동일! 다만, this에 binding할 객체는 똑같이 넣어주고 나머지 부분만 배열 형태로 넘겨줌.
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
var obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
}
};
obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
- call / apply 메서드 활용
1. 유사배열객체(array-like-object)에 배열 메서드를 적용
유사배열의 조건
1. 반드시 length 필요
2. index번호가 0번부터 시작해서 1씩 증가
//객체에는 배열 메서드를 직접 적용할 수 없어요.
//유사배열객체에는 call 또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있어요.
var 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 }
var arr = Array.prototype.slice.call(obj);
console.log(arr); // [ 'a', 'b', 'c', 'd' ]
//slice(): 배열로 부터 특정 범위를 복사한 값들을 담고 있는 새로운 배열 만듦.
//첫번째 인자: 시작 인덱스, 두번째 인자: 종료 인덱스=> 시작 인덱스부터 종료 인덱스까지 값 복사
2. Array.from 메서드(ES6)
// 유사배열
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
// 객체 -> 배열
var arr = Array.from(obj);
// 찍어보면 배열이 출력됩니다.
console.log(arr);
3. 생성자 내부에서 다른 생성자를 호출(공통된 내용의 반복 제거)
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
function Student(name, gender, school) {
Person.call(this, name, gender); // 여기서 this는 student 인스턴스!
this.school = school;
}
function Employee(name, gender, company) {
Person.apply(this, [name, gender]); // 여기서 this는 employee 인스턴스!
this.company = company;
}
var kd = new Student('길동', 'male', '서울대');
var ks = new Employee('길순', 'female', '삼성');
4. 여러 인수를 묶어 하나의 배열로 전달
//비효율
var numbers = [10, 20, 3, 16, 45];
var max = min = numbers[0];
numbers.forEach(function(number) {
// 현재 돌아가는 숫자가 max값 보다 큰 경우
if (number > max) {
// max 값을 교체
max = number;
}
// 현재 돌아가는 숫자가 min값 보다 작은 경우
if (number < min) {
// min 값을 교체
min = number;
}
});
console.log(max, min);
//효율
var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min);
// 펼치기 연산자(Spread Operation)를 통하면 더 간편하게 해결도 가능해요
const numbers = [10, 20, 3, 16, 45];
const max = Math.max(...numbers);
const min = Math.min(...numbers);
console.log(max min);
- bind 메서드:
: call과는 다르게 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하는 메서드
- 목적
- 함수에 this를 미리 적용!
- 부분 적용 함수 구현할 때 용이
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window객체
// 함수에 this 미리 적용
var bindFunc1 = func.bind({ x: 1 }); // 바로 호출되지는 않아요! 그 외에는 같아요.
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
// 부분 적용 함수 구현
var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9
- name 프로퍼티: bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 ‘bound’ 라는 접두어가 붙음(추적 용이)
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
var bindFunc = func.bind({ x:1 }, 4, 5);
// func와 bindFunc의 name 프로퍼티의 차이를 살펴보세요!
console.log(func.name); // func
console.log(bindFunc.name); // bound func
- 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
- 내부함수
- 메서드의 내부함수에서 메서드의 this를 그대로 사용하기 위한 방법
- self 등의 변수를 활용한 우회법보다 call, apply, bind를 사용하면 깔끔하게 처리 가능
var obj = {
outer: function() {
console.log(this); // obj
var innerFunc = function () {
console.log(this);
};
// call을 이용해서 즉시실행하면서 this를 넘겨주었습니다
innerFunc.call(this); // obj
}
};
obj.outer();
// bind()이용
var obj = {
outer: function() {
console.log(this);
var innerFunc = function () {
console.log(this);
}.bind(this); // innerFunc에 this를 결합한 새로운 함수를 할당
innerFunc();
}
};
obj.outer();
2. 콜백함수
- 콜백함수도 함수이기 때문에, 함수가 인자로 전달될 때는 함수 자체로 전달(this 유실!)
- bind메서드를 이용해 this를 입맛에 맞게 변경 가능
var obj = {
logThis: function () {
console.log(this);
},
logThisLater1: function () {
// 0.5초를 기다렸다가 출력해요. 정상동작하지 않아요.
// 콜백함수도 함수이기 때문에 this를 bind해주지 않아서 잃어버렸어요!(유실)
setTimeout(this.logThis, 500);
},
logThisLater2: function () {
// 1초를 기다렸다가 출력해요. 정상동작해요.
// 콜백함수에 this를 bind 해주었기 때문이죠.
setTimeout(this.logThis.bind(this), 1000);
}
};
obj.logThisLater1();
obj.logThisLater2();
- 화살표 함수의 예외사항
- 화살표 함수는 실행 컨텍스트 생성 시, this를 바인딩하는 과정이 제외
- 이 함수 내부에는 this의 할당과정(바인딩 과정)이 아예 없으며, 접근코자 하면 스코프체인상 가장 가까운 this에 접근
- this우회, call, apply, bind보다 편리한 방법
var obj = {
outer: function () {
console.log(this);
var innerFunc = () => {
console.log(this);
};
innerFunc();
};
};
obj.outer();
'항해99' 카테고리의 다른 글
[WIL] JavaScript의 ES(ECMA Script), ES5/ES6 문법 차이 (0) | 2023.04.09 |
---|---|
[항해99 1주차] JS문법 종합반 - 2주차 (0) | 2023.04.05 |
[항해99 1주차] JS문법 종합반 - 1주차 (0) | 2023.04.05 |
[항해99 온보딩]웹개발 종합반 4주차 (0) | 2023.03.23 |
[항해99 온보딩]웹개발 종합반 3주차 (0) | 2023.03.22 |
댓글