모든 내용의 출처는 코어 자바스크립트와 PoiemaWeb입니다.
https://poiemaweb.com/es6-block-scope
구글크롬(브라우저)에서 실행
console.log(this) // Window {window: Window, self: Window, document: document, name: "", location: Location, …}
전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로도 할당한다.
전역변수와 전역객체
var a = 1; console.log(a) // 1 console.log(window.1) //1
그러나 let으로 선언하면 전역객체의 프로퍼티로 할당하지 않는다.
전역변수와 전역객체(2)
let b = 1; console.log(b) //1 console.log(window.1) // undefined
전역객체는 모든 객체의 유일한 최상위 객체를 의미한다.
var 키워드로 선언된 변수는 전역 변수로 사용하면 전역 객체의 프로퍼티가 된다.
let 키워드로 선언된 변수는 전역 변수로 사용하는 경우, let 전역변수는 전역객체의 프로퍼티가 아니다.
let 전역변수는 보이지 않는 개념적인 블록내에 존재하게된다.
출처 : https://poiemaweb.com/es6-block-scope
함수로서의 호출, 메서드로서 호출
var func = function (x) { console.log(this, x); } func(1); // Window{...} 1
var obj = { method: func }; obj.method(2); // { method: f } 2
메서드 내부에서의 this
var obj = { methodA: function() { console.log(this }, inner: { methodB: function() { console.log(this) } } }
obj.methodA // { methodA: f, inner: { ... } } ( === obj) obj.inner.methodB // { methodB: f } ( === obj.inner )
내부함수에서의 this를 우회하는 방법
var obj = { outher: function() { console.log(this); // { outer: f } var innerFunc1 = function() { console.log(this); // Window{ ... } } innerFunc1(); //여기서 this를 변수에 할당 var self = this; var innerFunc2 = function() { console.log(self); // { outer: f } }; innerFUnc2(); } }; obj.outer()
this를 바인딩하지 않는 화살표 함수
var obj = { outer: function(){ console.log(this); // { outer: f } var innerFunc = () => { console.log(this); // { outer: f } } innerFunc(); } }; obj.outer()
여기서 this가 바인딩하는 것은 전역객체이기 때문에 이를 방지하는 방법을 말하고 있다.
생성자 함수
var Cat = function(name, age) { this.bark = '야옹', this.name = name, this.age = age; }; var nabi = new Cat('나비', 7); cosole.log(nabi) // Cat { bark: '야옹', name: '나비', age: 7 }
this에 별도의 대상을 바인딩하는 방법
Function.prototype.call(thisArg[,arg1[,arg2[, ...]]])
call 메서드
var func = function(a, b, c) { console.log(this, a, b, c); }
func(1, 2, 3) // Window{ ... } 1 2 3 func.call({ x: 1 }, 4, 5, 6) // { x: 1 } 4 5 6
Function.prototype.apply(thisArg[, argsArray])
apply 메서드
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 메서드는 명시적으로 별도의 this를 바인딩하면서
함수 또는 메서드를 실행하는 훌륭한 방법이지만
오히려 이로 인해 this를 예측하기 어렵게 만들어 코드 해석을 방해한다는 단점이 있다.
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
bind 메서드
var func = function(a, b, c, d) { console.log(this, a, b, c, d) } func(1, 2, 3, 4); // WIndow{ ... } 1 2 3 4
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); bindFunc2(6, 7) // { x: 1 } 4 5 6 7 bindFUnc2(8, 9) // { x: 1 } 4 5 8 9
name 프로퍼티
var func = function(a, b, c) { console.log(this, a, b, c); } var bindFunc = func.bind({ x:1 }, 4, 5)
console.log(func.name); // func console.log(bindFunc.name); // bound func
var obj = { outer: function(){ console.log(this); // { outer: f } var innerFunc = () => { console.log(this); // { outer: f } }; innerFunc(); } }