Program Tip

중첩 된 함수 내의 자바 스크립트 "this"포인터

programtip 2020. 10. 4. 13:10
반응형

중첩 된 함수 내의 자바 스크립트 "this"포인터


중첩 된 함수 시나리오에서 "this"포인터가 어떻게 처리되는지에 대한 질문이 있습니다.

다음 샘플 코드를 웹 페이지에 삽입한다고 가정 해 보겠습니다. 중첩 함수 "doSomeEffects ()"를 호출 할 때 오류가 발생합니다. Firebug에서 확인한 결과 중첩 된 함수에있을 때 "this"포인터가 실제로 전역 "window"개체를 가리키고 있다는 것을 나타냅니다. 객체의 함수 내에서 중첩 된 함수를 선언했기 때문에 제대로 이해하고 있지 않아야합니다. 함수와 관련하여 "로컬"범위를 가져야합니다 (예 : "this"포인터는 다음과 같이 객체 자체를 참조 할 것입니다. 내 첫 "if"문에서 어떻게되는지).

모든 포인터 (말장난 의도 없음)를 주시면 감사하겠습니다.

var std_obj = {
  options : { rows: 0, cols: 0 },
  activeEffect : "none",
  displayMe : function() {

    // the 'this' pointer is referring to the std_obj
    if (this.activeEffect=="fade") { }

    var doSomeEffects = function() {

      // the 'this' pointer is referring to the window obj, why?
      if (this.activeEffect=="fade") { }

    }

    doSomeEffects();   
  }
};

std_obj.displayMe();

JavaScript에서 this객체는 실제로 함수 호출 방법을 기반으로합니다.

일반적으로 this개체 를 설정하는 세 가지 방법이 있습니다 .

  1. someThing.someFunction(arg1, arg2, argN)
  2. someFunction.call(someThing, arg1, arg2, argN)
  3. someFunction.apply(someThing, [arg1, arg2, argN])

위의 모든 예에서 this객체는 someThing. 선행 부모 개체없이 함수를 호출하면 일반적으로 대부분의 브라우저에서 개체를 의미하는 전역 개체를 얻을 수 있습니다 window.


this클로저 범위의 일부가 아니므로 호출 사이트에 바인딩 된 함수에 대한 추가 매개 변수로 생각할 수 있습니다. 메서드가 메서드로 호출되지 않으면 전역 개체가 this. 브라우저에서 전역 개체는 window. 예를 들어, 다음 기능을 고려하십시오.

function someFunction() {
}

다음 객체,

var obj = { someFunction: someFunction };

다음과 같은 메서드 구문을 사용하여 함수를 호출하면

obj.someFunciton();

그런 다음 this에 바인딩됩니다 obj.

다음과 같이 someFunction ()을 직접 호출하면

someFunction();

그런 다음 this전역 개체, 즉 window.

가장 일반적인 해결 방법은 다음과 같은 클로저에이를 캡처하는 것입니다.

displayMe : function() {      

    // the 'this' pointer is referring to the std_obj      
    if (this.activeEffect=="fade") { }      
    var that = this;  
    var doSomeEffects = function() {      

      // the 'this' pointer is referring to global
      // that, however, refers to the outscope this
      if (that.activeEffect=="fade") { }      
    }      

    doSomeEffects();         
 }      

이 질문이 가장 많이 찬성 된 질문 중 하나 인 것처럼 보이므로 몇 년이 지난 후에도 화살표 기능을 사용하는 ES6 솔루션을 추가하겠습니다.

var std_obj = {
  ...
  displayMe() {
    ...
    var doSomeEffects = () => {
                        ^^^^^^^    ARROW FUNCTION    
      // In an arrow function, the 'this' pointer is interpreted lexically,
      // so it will refer to the object as desired.
      if (this.activeEffect=="fade") { }
    };
    ...    
  }
};

엔클로저 변수와 "this"에는 차이가 있습니다. "this"는 실제로 함수 호출자에 의해 정의되는 반면 명시 적 변수는 인클로저로 알려진 함수 선언 블록 내부에 그대로 남아 있습니다. 아래 예를 참조하십시오.

function myFirstObject(){
    var _this = this;
    this.name = "myFirstObject";
    this.getName = function(){
       console.log("_this.name = " + _this.name + " this.name = " + this.name);  
    }
}

function mySecondObject(){
    var _this = this;
    this.name = "mySecondObject";
    var firstObject = new myFirstObject();
    this.getName = firstObject.getName
}

var secondObject = new mySecondObject();
secondObject.getName();

여기에서 시도해 볼 수 있습니다 : http://jsfiddle.net/kSTBy/

What's happening in your function is "doSomeEffects()", is being called explicitly, this means context or the "this" of the function is the window. if "doSomeEffects" was a prototype method e.g. this.doSomeEffects on say "myObject", then myObject.doSomeEffects() would cause "this" to be "myObject".


To understand this question , try to get the output for the following snippet

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        (function() {
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        }());
    }
};
myObject.func();

The above code will output the following to the console:

outer func:  this.foo = bar
outer func:  self.foo = bar
inner func:  this.foo = undefined
inner func:  self.foo = bar

In the outer function, both this and self refer to myObject and therefore both can properly reference and access foo.

In the inner function, though, this no longer refers to myObject. As a result, this.foo is undefined in the inner function, whereas the reference to the local variable self remains in scope and is accessible there. (Prior to ECMA 5, this in the inner function would refer to the global window object; whereas, as of ECMA 5, this in the inner function would be undefined.)


As explained by Kyle, you could use call or apply to specify this within the function:

Here is that concept applied to your code:

var std_obj = {
    options: {
        rows: 0,
        cols: 0
    },
    activeEffect: "none",
    displayMe: function() {

        // the 'this' pointer is referring to the std_obj
        if (this.activeEffect == "fade") {}

        var doSomeEffects = function() {
            // the 'this' pointer is referring to the window obj, why?
            if (this.activeEffect == "fade") {}
        }

        doSomeEffects.apply(this,[]);
    }
};

std_obj.displayMe();

JsFiddle

참고URL : https://stackoverflow.com/questions/9644044/javascript-this-pointer-within-nested-function

반응형