'var that = this;'는 무엇입니까? JavaScript에서 의미 하는가?


351

JavaScript 파일에서 나는 보았다 :

function Somefunction(){
   var that = this; 
   ... 
}

이것을 선언 that하고 할당 하는 목적은 무엇입니까 this?



6
화살표 기능에는 "this"및 "that"핵이 필요하지 않습니다. 화살표 기능을 사용하면 "this"가 예상대로 작동합니다. 자세한 내용은 여기를 참조하십시오 ES6 심도 : 화살표 기능
satguru srivastava

1
여기의 개념을 설명한다 scotch.io/@alZami/understanding-this-in-javascript
AL-zami

상황에 따라 신비이 동작에 대한 좋은 설명은 여기
통화 연결음

및 최신 업데이트 된 설명은 찾을 수 있습니다 여기에
Sukrit 굽타

답변:


486

이 답변을 그림으로 시작하겠습니다.

var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
    // this is a reference to the element clicked on

    var that = this;

    colours.forEach(function() {
        // this is undefined
        // that is a reference to the element clicked on
    });
});

내 대답은 원래 jQuery로 이것을 보여주었습니다. 매우 약간 다릅니다.

$('#element').click(function(){
    // this is a reference to the element clicked on

    var that = this;

    $('.elements').each(function(){
        // this is a reference to the current element in the loop
        // that is still a reference to the element clicked on
    });
});

this새 함수를 호출하여 범위를 변경하면 자주 변경 되므로 이를 사용하여 원래 값에 액세스 할 수 없습니다. 에 대한 별칭을 지정 that하면의 원래 값에 계속 액세스 할 수 있습니다 this.

개인적으로, 나는 that별칭으로 사용하는 것을 싫어합니다 . 특히 함수가 두 줄보다 긴 경우 참조하는 내용이 분명하지 않습니다. 나는 항상 더 설명적인 별칭을 사용합니다. 위의 예제에서는 아마도을 사용 clickedEl합니다.


149
나는 보통 함께 간다 var self = this;. 단어 that는 변수가 무엇이든 암시하는 것처럼 보입니다 this.
David Murdoch

13
@David 예 나는 다소 오해의 소지 가 있다고 생각 했습니다 . 그러나 Crockford가 말했듯이, 그것이 관습이라면, 그 길을 따르는 것이 현명합니다. 나는 당신에게 완전히 동의하지만 훨씬 더 이해가됩니다.
El Ronnoco

4
@El Ronnoco, 그러나 "그는 흰머리와 딱딱한 수염을 띠고 그의 태도는 아이들이 잔디밭에서 내리라고 소리 치는 심술쟁이 노인을 생각 나게합니다." - blogging.compendiumblog.com/blog/software-for-humans/0/0/... ;-p
데이비드 머독

7
@ElRonnoco :하지만 그것은 권위에 대한 호소입니다. "유명한 사람들"이해야 할 말만하면 재난으로 향하게됩니다.
궤도에서 가벼움 경주

3
forEach함수는 함수의 결합 된 제 2 선택적 인수 IS 걸린다. colours.forEach(function(){/* 'this' is bound correctly --> */}, this);따라서 실제로 필요 var that = this하지 않은 메모를 추가해야합니다 . forEach
Matt Clarkson

107

에서 크록 포드

관례 적으로 우리는 변수를 비공개로 만듭니다 . 개인 메소드가 오브젝트를 사용할 수 있도록하는 데 사용됩니다. 이 원인 인 ECMAScript 언어 사양의 오류에 대한 해결 방법입니다 이것은 내부 기능을 위해 잘못 설정 될 수 있습니다.

JS 피들

function usesThis(name) {
    this.myName = name;

    function returnMe() {
        return this;        //scope is lost because of the inner function
    }

    return {
        returnMe : returnMe
    }
}

function usesThat(name) {
    var that = this;
    this.myName = name;

    function returnMe() {
        return that;            //scope is baked in with 'that' to the "class"
    }

    return {
        returnMe : returnMe
    }
}

var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
      "UsesThis thinks it's called " + usesthis.returnMe().myName);

이 경고 ...

그것이 Dave라고 생각합니다.

이것은 이것이 undefined라고 생각합니다.


2
고마워요.
Chris

3
나는 세부 사항이 없기 때문에 이해하지 못했고 Google에서 검색 하여이 페이지를 찾았습니다. 나는 다시 같은 문장을 지적했다. 따라서 공감.
Aditya MP

3
나는 JavaScript에 익숙하지 않은 사람이 내 대답만으로 개념을 이해하기 어려울 것이라고 말할 것입니다. 나는 매우 간단히 대답했다 (그리고 나는 당신이 구글에 대한 페이지로 링크했다.
El Ronnoco 2013

16
나는 범죄하지 않습니다. downvoting 할 때 의견을 말하는 사람을 만나서 반갑습니다!
El Ronnoco

4
Crockford의 대답의 문제는 that변수가 그의 예제에서 전혀 사용되지 않는다는 것입니다. 변수 홀딩을 만드는 것만으로 this나머지 코드에 영향 을 미치는 것처럼 보입니다 .
r3m0t

86

이것은 내부 함수 (다른 함수 내에 정의 된 함수)가 더 작동하도록 해킹하는 것입니다. 자바 스크립트에서 한 함수를 다른 함수 안에 정의 this하면 전역 범위로 자동 설정됩니다. this외부 함수에서와 동일한 값 을 기대 하기 때문에 혼동 될 수 있습니다 .

var car = {};
car.starter = {};

car.start = function(){
    var that = this;

    // you can access car.starter inside this method with 'this'
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to the global scope
        // 'this.starter' is undefined, so we use 'that' instead.
        that.starter.active = true;

        // you could also use car.starter, but using 'that' gives
        // us more consistency and flexibility
    };

    activateStarter();

};

이것은 ( car.start예 와 같이) 객체의 메소드로 함수를 생성 한 다음 해당 메소드 내에 함수 (예 :)를 생성 할 때 특히 문제가됩니다 activateStarter. 최상위 수준 방법 this에서 객체를 가리키는 방법 (이 경우 car)이지만 내부 함수에서 this이제 전역 범위를 가리 킵니다. 이것은 고통이다.

두 범위에서 규칙으로 사용할 변수를 작성하는 것은 자바 스크립트의 일반적인 문제에 대한 해결책입니다 (jquery 함수에서도 유용합니다). 이것이 가장 일반적인 소리 이름 that이 사용되는 이유 입니다. 언어의 단점을 극복하기 위해 쉽게 인식 할 수있는 규칙입니다.

Douglas Crockford의 El Ronnoco 힌트와 마찬가지로 이것이 좋은 생각이라고 생각합니다.


8
나는 이것이 허용 된 것보다 더 유용한 대답이라고 생각합니다. 왜냐하면 Crockford가 "그것"을 발명 한 이유는 명확하지만 jQuery에 대한 답변은 그렇지 않습니다.
Konstantin Smolyanin

4
이것은 실제로 받아 들여진 대답보다 더 나은 예입니다. Douglas는 "ECMAScript 언어 사양에서 오류가 발생하여 내부 기능에 대해 잘못 설정되는 오류"와 같은 내용을 설명합니다.
kakacii

1
그래도 문법을 올바르게 만들 수 있습니다. 나는 그것이 오타와 비슷하다는 것을 알고 있지만,이 질문은 초보자와 비슷하기 때문에 자바 스크립트 초보자를 혼란스럽게 할 수 있습니다. 다음과 같아야합니다. var car = {}; car.starter = {}; car.start = function () {...}
kakacii

1
@kakacii 감사합니다. 지금 수정했습니다.
Waylon Flinn

9

의 사용은 that당신의 사용과 해결 만들면 정말 필요하지 않습니다 call()또는 apply():

var car = {};
car.starter = {};

car.start = function(){
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to our main object
        this.starter.active = true;
    };

    activateStarter.apply(this);
};

3

때때로 this다른 범위를 참조하고 다른 것을 참조 할 수 있습니다. 예를 들어 DOM 이벤트 내에서 생성자 메소드를 호출하려는 경우 (이 경우)this 생성 된 객체가 아닌 DOM 요소를 참조합니다.

HTML

<button id="button">Alert Name</button>

JS

var Person = function(name) {
  this.name = name;
  var that = this;
  this.sayHi = function() {
    alert(that.name);
  };
};

var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad

데모

assing 의지 위의 솔루션 thisthat내부의 이름 속성 다음 우리가 할 수있는 접근 sayHi의 방법that 이 그래서는 DOM 호출 내부 문제없이 호출 할 수 있습니다.

또 다른 해결책은 빈 that객체 를 할당하고 속성과 메서드를 추가 한 다음 반환하는 것입니다. 그러나이 솔루션을 사용 prototype하면 생성자 를 잃어 버렸습니다 .

var Person = function(name) {
  var that = {};
  that.name = name;
  that.sayHi = function() {
    alert(that.name);
  };
  return that;
};

2

예제는 다음과 같습니다.

$(document).ready(function() {
        var lastItem = null;
        $(".our-work-group > p > a").click(function(e) {
            e.preventDefault();

            var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
            if (item == lastItem) {
                lastItem = null;
                $('.our-work-single-page').show();
            } else {
                lastItem = item;
                $('.our-work-single-page').each(function() {
                    var imgAlt = $(this).find('img').attr('alt'); //Here value of "this" is '.our-work-single-page'. 
                    if (imgAlt != item) {
                        $(this).hide();
                    } else {
                        $(this).show();
                    }
                });
            }

        });
    });`

따라서 대상의 DOM 요소에 따라이 값이 서로 다른 두 값이라는 것을 알 수 있습니다. 그러나 위의 코드에 "that"을 추가하면 "this"의 값이 변경됩니다.

`$(document).ready(function() {
        var lastItem = null;
        $(".our-work-group > p > a").click(function(e) {
            e.preventDefault();
            var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
            if (item == lastItem) {
                lastItem = null;
                var that = this;
                $('.our-work-single-page').show();
            } else {
                lastItem = item;
                $('.our-work-single-page').each(function() {
                   ***$(that).css("background-color", "#ffe700");*** //Here value of "that" is ".our-work-group > p > a"....
                    var imgAlt = $(this).find('img').attr('alt'); 
                    if (imgAlt != item) {
                        $(this).hide();
                    } else {
                        $(this).show();
                    }
                });
            }

        });
    });`

..... $ (that) .css ( "배경색", "# ffe700"); // var의 값이 "this"이므로 "that"의 값은 ".our-work-group> p> a"입니다. 따라서 "this"= '.our-work-single-page'에 있어도 "that"을 사용하여 이전 DOM 요소를 조작 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.