[Javascript] this

Code/JavaScript 2019. 7. 19. 21:11


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
Posted by codens