함수 호출 스택 분석
가장 바깥은 anonymous 가 호출 된다 그 이후 차례대로 코드에 적힌 함수 호출
스코프 체인
ES2015 부터 scope 는 이제 블록{} 단위이다. 원래는 function 단위였다고 함
const x = "x";
function c() {
const y = 'y';
console.log(c);
function b() {
const z = 'z'
console.log('b')
}
}
function a() {
const x= 'x';
console.log('a');
b();
}
a();
c();
scope 분석을 해보자 == lexical scope , 한번 코딩 해놓으면 scope는 바뀌지 않음
c -> anonymous
a -> anonymous
b -> c-> anonymous
이걸 기반으로 mapping을 해보자
anonoymous -> {x,c,a}
c -> {y,b}
b ->{z}
a -> {x}
이때 a에서 b가 접근이 가능한가?
1. a scope에서 b를 찾을수 있는가? -> x 밖에없다. 못찾음
2. a 의 부모 scope 인 anonymous 에서 b를 찾을 수 있는가? -> x,c,a 가 있다. 못찾음
그럼 b에서 a 접근이 가능한가?
위와 동일하게 b scope 먼저 확인 -> 없음 -> anonymous scope 확인 x,c,a 존재함 찾음 -> 접근 가능 (호출 가능)
호이스팅
발동이 안되게 하는것이 가장 좋다.
var, function 은 다 맨위로 올라가 진다. let ,const 는 그렇지 않음
function c() {
function b() {
a();
}
b();
}
c();
function a() {
console.log("worked");
}
b -> c-> anonymous
a -> anonymous
mapping을 하면
anonymous -> {b, a}
c -> {b}
a -> {}
b -> {}
b의 scope에 a가 있나 ? -> 없음 -> 부모인 c scope 에 a 선언이 있나? -> 없음 -> 부모인 anonymous scope 에 있나? a가 존재함 이떄
const a = () => { console.log('a') }
이런 식으로 존재할 경우 호이스팅이 되지 않아 undefined 가 뜨게 된다.
선언은 다 맨위에서 하자
this
일반 function 안에서 선언된 this는 해당 함수가 호출되는 시점에서 this가 결정이 된다.
arrow function의 경우에는 자신의 부모 scope가 this 가 된다.
const obj = {
name: 'tony',
sayName() {
console.log(this.name)
}
}
obj.sayName()
// tony
const sayN = obj.sayName
sayN()
// window.name 이 호출되게 된다.
function Human(name) {
this.name = name;
}
new Human('tony')
// this 가 객체 자기자신을 가르킴
this 가 바뀌는 경우 1. new 를 통해 호출하거나 2. obj.sayName 처럼 앞에 객체가 붙는 경우 바뀐다.
function sayName() {
console.log(this.name)
}
sayName();
//this == window
sayName.bind({name:'tony'})
sayName.apply({name:'tony'})
sayName.call({name:'tony'})
this를 bind할 수 있다. apply,call은 bind하고 호출 까지 하는것이다.
https://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply
const obj = {
name: 'tony',
sayName() {
console.log(this.name)
function inner() {
console.log(this.name);
}
inner();
}
}
obj.sayName()
// obj.name = tony
// window
inner는 호출하는 시점에 new, object 같은것이 앞에 붙어서 호출된게 아니다. 그래서 this 가 window로 바뀌지 않는다.
const obj = {
name: 'tony',
sayName() {
console.log(this.name)
const inner = () => {
console.log(this.name);
}
inner();
}
}
obj.sayName()
이 arrow function인 경우에는 부모 scope의 this를 가져오게 된다.
부모의 this == obj 이것을 그대로 가져오게 되어 tony가 호출된다.
만약 부모가 호출을 안당했으면 inner의 this 는 모르는것이다.
header.addEventListener('click',function() {
console.log(this)
})
이 경우 this 가 뭔지 알수가 없다. (header로 나오지만) anonymous function 은 호출된적이 없다. 호출된건 addEventListener 함수이다.
하지만 예측을 해보면
const header = {
addEventListener: function(eventName , callback) {
callback.call(header);
}
}
이런식으로 this를 header로 맵핑해줬을것이라고 예상해볼수 있다.
'FrontEnd > 인간 JS 엔진되기' 카테고리의 다른 글
2. promise ,async await , closure (0) | 2022.06.04 |
---|