https://poiemaweb.com/js-this
* 렉시컬 스코프(Lexical scope)
렉시컬 = 정해진, 정적, 사전적, 어휘적,
- 소스코드가 작성된 그 문맥에 의해 결정
함수를 선언한 위치에 따라 스코프가 결정되는 것
함수를 어디서 호출하는지가 아님
* 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정
- 함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프(Lexical scope)는 함수를 선언할 때 결정된다. this 바인딩과는 다르다
* 함수 호출 방식에 따른 this
var foo = function () {
console.dir(this);
};
// 1. 함수 호출
foo(); // window , "use strict" 사용시 undefined
window.foo(); // window
// 2. 메소드 호출
var obj = { foo: foo };
obj.foo(); // obj
// 3. 생성자 함수 호출
var instance = new foo();
// 4. apply/call/bind 호출
var bar = { name: 'bar' };
foo.call(bar); // bar
//========================================
* 기본적으로 전역(Window, Global) 참조 , "use strict"를 쓰면 모두 undefined
- 일반 함수 호출
- 내부함수(객체의 메소드의 내부함수 포함)
- 콜백함수
//================================
< 예외의 경우(전역 객체를 가르키지 않는 경우) >
* 객체의 메소드 : 객체
* call(), apply(), bind() 로 객체를 자정한 경우
* 이벤트 : 객체 (DOM...)
- addEventListener()
* 화살표 함수 : 언제나 상위 스코프의 this를 참조 (Lexical this)
코드의 바로 바깥의 객체의 this
- 생성자 함수로 사용할수 없음(new 사용안됨)
- call(), apply(), bind() 사용 안됨
* 생성자 함수 : 생성자 함수로 생성된 인스턴스
* strict mode의 일반 함수 : undefined
* jQuery.each() 내부 : 인자값
//=======================
* call(), apply(), bind()
- 함수는 객체
- call(), apply(), bind() 는 함수의 기본 Method
- 실행영역을 지정
- call(), apply() 는 함수를 실행
- bind()는 함수를 반환
//==================
* 화살표 함수
http://webframeworks.kr/tutorials/translate/arrow-function/
- 화살표 함수에서의 lexical this로 실행된다.
x => x + this.y
- 다음과 동일
function (x) { return x + this.y }.bind(this)
//========================
* 생성자 함수
- new 사용하여 생성한 함수
// 생성자 함수
function Person(name) {
this.name = name;
}
var me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
// new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수로 동작하지 않는다.
var you = Person('Kim');
console.log(you); // undefined
//==============================================
//==============================================
<script>
function disp(str, _this, val1=null) {
console.log(str, typeof _this, _this.constructor.name, window === _this, _this.name, _this.arr, val1);
}
var name = 'WINDOW';
var arr = [1,2];
function func1(){
disp("func1 = ", this); //Window
func1_2();//Window
func1_2.call(obj1);//obj1 <========= call() 로 객체 지정
function func1_2(){
disp("func1_2 = ", this); //Window
}
}
var obj1 = {
name: 'OBJ1',
arr: [100,200],
func2: function(){
disp("obj1-func2", this); //Object <======= 객체의 메소드
func2_2();
function func2_2(){ disp("obj1-func2-2", this); }//Window , 내부 함수도 Window 참조
},
func3: () => { disp("obj1-func3", this); },//Window , 화살표 함수는 한단계 위를 참조, Object에 Method로 사용은 비추
};
func1();//Window
obj1.func2();//Object <======= 객체의 메소드
obj1.func3();//Window
arr.forEach( function(){
disp("forEach = ", this); //Window
});
console.log('=======================================================');
//call(), apply(), bind()
//call(), apply()는 함수를 실행
//bind()는 함수를 반환
func1.call(obj1, 1,2,3);//obj1 <=========
func1.apply(obj1, [1,2,3] );//obj1, call()과 같고, 인자로 배열 사용
var func2 = func1.bind(obj1);
func2();//obj1
//========================
console.log('=======================================================');
//event
Array.from( document.querySelectorAll('.list li') ).forEach( ele => {
ele.addEventListener('click', function(event){
disp("event = ", this);//HTMLLIElement , DOM 객체
});
});
//jQuery
/* console.log('=======================================================');
$.each(arr, function(){
disp(".each func = ", this); //Number <=======
$.each(arr, function() {
disp(".each func -> .each func = ", this); //Number <======= jQuery
});
$.each(arr, () => {
disp(".each func -> .each Arrow = ", this); //Number <======= 화살표 함수는 바로위를 참조
});
arr.forEach( function(){
disp(".each func -> forEach func = ", this); //Window
});
arr.forEach( () => {
disp(".each func -> forEach Arrow = ", this); //Number <=======
});
});
console.log('=======================================================');
$.each(arr, () => {
disp(".each Arrow = ", this); //Window
$.each(arr, function() {
disp(".each Arrow -> .each func = ", this); //Number <======= jQuery
});
$.each(arr, () => {
disp(".each Arrow -> .each Arrow = ", this); //Window
});
arr.forEach( function(){
disp(".each Arrow -> forEach func = ", this); //Window
});
arr.forEach( () => {
disp(".each Arrow -> forEach Arrow = ", this); //Window
});
}); */
</script>
//==============================================
//===============
//
https://velog.io/@rohkorea86/this-%EC%99%80-callapplybind-%ED%95%A8%EC%88%98-mfjpvb9yap
https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd
https://www.w3schools.com/js/js_this.asp
http://w3schools-fa.ir/js/js_this.html
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
'Code > JavaScript' 카테고리의 다른 글
[Javascript] 호이스팅(Hoisting) (0) | 2019.07.20 |
---|---|
[Javascript] 웹 워커, Web Worker (0) | 2019.07.20 |
[Javascript] ES2015 객체 리터럴 (0) | 2019.07.19 |
NPM 사용법 (0) | 2019.04.10 |
npm fsevents 경고 메시지 없애기 (1) | 2019.04.10 |