문제

나는 다음을 가지고 있습니다 :

var o = {f: function(fn) {
    fn.call(o);
}};
var ob = {f: function() {
    o.f(function() {
        this.x = 2; //HERE: how can this reference ob?
        //ob.x = 2;
    });
}};
ob.f();
ob.x; // undefined

o.f(fn) 전화 fn 어디 this o에 묶여 있습니다.

HERE에서 사용하고 싶습니다 this ob에 액세스하려면그러나 언제 ob.f 라고, this ~에 묶여 있다 o.JQuery는 이렇게 작동하는 것 같아요.예를 들어:

$(...).blah(function() {
    this // this is bound to $(...) jquery object.
    ...
};

내가 지금 하고 있는 일은:

var Ob = function() {
    var self = this;
    self.f = function() {
        o.f(function() { self.x = 2; };
    };
};
var ob = new Ob();
ob.f();
ob.x; // 2

그러나 나는 문체상의 이유로 위의 내용을 좋아하지 않습니다.

  1. 사용하여 new 연산자가 너무 고전적인 OOP처럼 들립니다.
  2. 정의 수업 Ob 사용하여 function (적어도 처음에는) 직관적이지 않습니다.

그래서 나는 정의하려고 노력한다. ob 객체 리터럴로.하지만 개체를 ​​참조하는 방법을 찾을 수 없습니다. ob 메서드 호출을 사용하는 함수에서 this 이외의 다른 물체에 ob.

다음과 같은 작업을 수행할 수 있습니다.

var ob = {f: function() {
    o.f(function() {
        self.x = 2;
    });
}};
var self = ob;
ob.f();
ob.x;

하지만 위의 요소를 어떻게 고려해야할지 모르겠습니다.나는 시도했다:

function obj(o) {
    return function() {
        var self = o;
        return o;
    }();
}
var ob = obj({f: function() {
    o.f(function() {
        self.x = 2;
    });
}});
ob.f();
ob.x;// ReferenceError: self is not defined

따라서 객체 내부의 함수에서 객체를 안정적으로 참조하는 방법이 있습니까 (this 상황에 따라 무엇이든 바인딩할 수 있나요?

도움이 되었습니까?

해결책

Douglas Crockford의 간단한 생성자 패턴에 따라 new 대신 객체 리터럴을 사용하는 생성자 함수를 만들겠습니다.이와 같이:

var o = {f: function(fn) {
    fn.call(o);
}};

function obj() {
    var me = {};
    me.f = function () {
        o.f(function() {
            me.x = 2;
        });
    };
    return me;
}

var ob = obj();
ob.f();
ob.x; // 2

다른 팁

JavaScript에서 함수는 함수를 호출하는 두 가지 메서드가 있는 객체입니다.

call(scope, arg1, arg2, ...);
apply(scope, args);  // args is an array of arguments to call the function with

첫 번째 인수 'scope'는 함수 내에서 'this'에 바인딩된 개체입니다.따라서 다음 예는 동일합니다.

obj.method(1, 2, 3);
obj.method.call(obj, 1, 2, 3);
obj.method.apply(obj, [1, 2, 3]);

첫 번째 예에서는 'o'를 범위로 사용하여 o.f()에 전달된 함수를 호출합니다.

var o = {f: function(fn) {
    fn.call(o);
}};

따라서 'ob'에 전달된 함수는 다음과 같이 'o'를 참조합니다.

var ob = {f: function() {
    o.f(function() {
        this.x = 2; //HERE: how can this reference ob?
        //ob.x = 2;
    });
}};

'HERE' 줄에서 'this'는 실제로 'o'입니다.

다음을 시도해 볼 수 있습니다.

var ob = {f: function() {
    var self = this;
    o.f(function() {
        self.x = 2; // self is ob now
    });
}};

또는 'o.f' 함수를 수정하여 범위 매개변수를 취할 수도 있습니다.

var o = {f: function(fn, scope) {
    fn.call(scope || this); // Uses the given scope or this (= 'o') if no scope is provided
}};

그런 다음 'ob'에 'this'를 전달할 수 있습니다.

var ob = {f: function() {
    o.f(function() {
        this.x = 2; // 'this' will be the 'outer' this
    }, this); // Here: this as scope
}};

리터럴을 사용하여 보조 기능 없이 이를 수행할 수 있습니다.

var o = {f: function(fn) {
    fn.call(o);
}};
var ob = {f: function() {
    var self = this; // this == ob
    o.f(function() {
        self.x = 2; // self == enclosing function's this == ob
    });
}};
ob.f();
assert(ob.x == 2);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top