기본적으로 this는 전역객체에 바인딩 된다고 했고, 아래의 예시는 브라우저와 Node.js환경일 때 전역객체와 this다.
브라우저 환경
console.log(this); // { alert: f(), atob: f(), blur: f(), btoa: f(), ... }
console.log(window); // { alert: f(), atob: f(), blur: f(), btoa: f(), ... }
console.log(this === window); // true
console.log(this); // { process: { title: 'node', version: 'v10.13.0',... } }
console.log(global); // { process: { title: 'node', version: 'v10.13.0',... } }
console.log(this === global); // true
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
let a = 1;
console.log(a); // 1
console.log(window.a); // undefined
console.log(this.a); // undefined
함수를 실행할때는, 여러가지 방법이 있는데 그중 가장 일반적인 방법 두가지는 함수로 호출하는 경우와 메서드로서 호출하는 경우이고, 이 둘을 구분하는 유일한 차이는 독립성입니다,
독립성
함수는 메서드를 포함하고있는 개념이고, 독립성이라는 것을 쉽게 말하자면 함수는 직접 호출 가능하고, 메서드는 객체 안에서 호출을 하는 한단계 이상 거쳐서 호출할 수 있다고 생각하면 좋을 것 같다.
function fn() {
console.log("함수");
}
const obj = {
method: function () {
console.log("메서드");
},
};
fn();
obj.method();
함수와 메서드 호출
var func = function (x) {
console.log(this, x);
};
func(1); // Window { ... } 1
var obj = {
method: func,
};
obj.method(2); // { method: f } 2
그렇다면 아까 내부함수에서도 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();
var obj = {
outer: function() {
console.log(this); // (1) { outer: f }
var innerFunc1 = function() {
console.log(this); // (2) Window { ... }
};
innerFunc1();
var self = this;
var innerFunc2 = function() {
console.log(self); // (3) { outer: f }
};
innerFunc2();
},
};
obj.outer();
var obj = {
outer: function() {
console.log(this); // (1) { outer: f }
var innerFunc = () => {
console.log(this); // (2) { outer: f }
};
innerFunc();
},
};
obj.outer();
setTimeout(function() {
console.log(this);
}, 300); // (1)
[1, 2, 3, 4, 5].forEach(function(x) {
// (2)
console.log(this, x);
});
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
// (3)
console.log(this, e);
});
var Cat = function(name, age) {
this.bark = '야옹';
this.name = name;
this.age = age;
};
var choco = new Cat('초코', 7);
var nabi = new Cat('나비', 5);
console.log(choco, nabi);
/* 결과
Cat { bark: '야옹', name: '초코', age: 7 }
Cat { bark: '야옹', name: '나비', age: 5 }
*/
const func = function (a, b, c) {
console.log(this, a, b, c);
};
func.call({ this: "this" }, 1, 2, 3);
func.apply({ this: "this" }, [1, 2, 3]);
const func = function (a, b, c) {
console.log(this, a, b, c);
};
func.call({ this: "this" }, 1, 2, 3); // {this: 'this'} 1 2 3
func.apply({ this: "this" }, [1, 2, 3]); // {this: 'this'} 1 2 3
func.bind({ this: "this" }, [1, 2, 3]); // 함수 실행이 안되어있음
func.bind({ this: "this" }, 1, 2, 3)(); // {this: 'this'} 1 2 3
const obj = {
name: "JavaScript",
func: function () {
console.log(this);
},
};
obj.func(); // {name: 'JavaScript', func: ƒ}
obj.func.call("this"); // String {'this'}
const ObjFunc = function (name) {
this.name = name;
};
const objFunc = new ObjFunc("JavaScript");
console.log(objFunc); // ObjFunc {name: 'JavaScript'}
const bindObjFunc = ObjFunc.bind("typeScript");
console.log(bindObjFunc("typeScript"));// new 로 생성하지 않으면, 아예 찾지 못하는 듯
const ts = new bindObjFunc("JavaScript"); // ObjFunc {name: 'JavaScript'}
console.log(ts); //ObjFunc {name: 'JavaScript'}
참고 : 코어자바스크립트
참고 : [10분 테코톡] 하리의 this youTube 영상