2012-06-06 5 views
21

다음을 달성하기위한 최상의 설계 패턴은 무엇입니까 (작동하지 않음)?자바 스크립트 : 해당 객체 내에서 객체 메소드 호출하기

var obj = (function() { 

    // code defining private variables and methods 

    var _obj = { 
    property: value, 
    method1: function() { 
     // do stuff 
    }, 
    method2: function() { 
     // use property 
     var prop = _obj.property; // obviously doesn't work 
     // call method1 
     obj.method1(); // "obj" not finished being defined yet! 
    } 
    }; 

    // obviously now I could do... 
    var prop = _obj.property; 

    return _obj; 

})(); 

// and I could now do... 
obj.method1(); 

내가 마찬가지로

var obj = (function() { 

    var property = value, 
     method1 = function() { 
     // do stuff 
     }, 
     method2 = function() { 
     // use property 
     var prop = property; 
     // call method1 
     method1(); 
     }, 
     _obj = { 
     property: property, 
     method1: method1, 
     method2: method2 
     }; 

    return _obj; 

})(); 

입니다 작동해야한다고 생각 변형, 어떻게 객체가 new 연산자로 생성 할 의미 작동합니까? 생성자 함수 자체 내에서 을 작성할 수 있습니다. 그러나 생성자를 작게 유지하고, 생성시 사용자 정의 될 가능성이 높은 것들만 정의한 다음 나머지를 프로토 타입에 정의하려면 어떻게해야할까요? (이것이 일반적인 패턴 인 것 같습니다.) 프로토 타입 내의 프로퍼티/메소드는 어떤 식 으로든 상호 작용할 수 있습니까?

var MyObj = function(name) { 
    this.name = name; 
}; 

var obj = new MyObj('Bob'); 

MyObj.prototype = { 
    called_often: function() { 
    // lots more code than just the following 
    return document.getElementById('someID').value; 
    }, 

    global_default: 'value', // can be changed, so need to pull value when run 

    does_stuff: function(value) { 
    var str = global_default + value, // can't access global_default on its own 
     input = MyObj.called_often(), // doesn't work; MyObj.prototype.called_often() DOES 
     name = this.name; // 'this' used in the prototype doesn't work 
          // even within a created object 
    return name + input + str; 
    } 
}; 

이 문제가 발생할 때마다 내 결과를 얻을 수있는 더 좋은 방법이있을 것입니다. 이 코드는 특정 상황이 아니며 일반적인 문제를 보여줍니다. 따라서 당신은 제가 처한 특정 상황에 대한 대안을 제게 줄 수 없을 것입니다. 하지만 어쩌면 당신은 내 전반적인 생각을 도울 수 있습니다.

답변

26

음, 첫 번째 예에서 : this 값입니다 무엇

var _obj = { 
    property: value, 
    method1: function() { 
     // do stuff 
    }, 
    method2: function() { 
     // use property 
     var prop = this.property; 
     // call method1 
     this.method1(); 
    } 
    }; 

.

이제는 개체 리터럴 구문의 다른 곳에서 온 "건설 중"개체의 속성을 참조하면됩니다. 예를 들어 구문 적으로 가능하지 않기 때문에 예제를 제시하기가 어렵습니다. 원하는 경우에는 하나 이상의 개별 대입 문이 필요합니다.

+0

나는 'this'가 new + 생성자로 생성되었거나 call/apply를 사용하는 경우에만 객체를 가리킨다 고 생각했습니다. 하지만 당신 말이 맞아요. 분명히 나는이 모든 시간을 혼란스러워했다. 또한 나는 그것을 시도했다고 생각했다. 그러나 명백하게. –

+0

JavaScript는 놀라 울 정도로 간단하고 동시에 놀랍도록 복잡합니다 .-) 그것은 'this'가 함수가 호출 될 때 바인드 된 것으로 밝혀졌습니다. 그러나 그 간단한 규칙은 모든 종류의 흥미로운 세부 사항을 이끌어 낸다. – Pointy

+0

안녕하세요, 뾰족한. 나는 같은 유형의 문제가있다. 저는'roundslider.js'를 사용하고 있습니다. 당신이 작성한 함수를 호출하고 있습니다. 그러나 그것은 나를 위해 오류입니다. '$ ("# slider") roundSlider ({ 변경 : 기능 (이벤트) { traceEvent() }, ' }); – locateganesh

9

어째서? 단순한 물건을 복잡하게 만들고 있습니다. Pointy의 대답은 좋지만 몇 가지 이유로 프로토 타입 방식이 더 좋습니다. 그래서 제가 마지막 방법을 설명하고 있습니다 (오히려 수정합니다). Check this fiddle.

var MyObj = function(name) { 
    this.name = name; 
}; 

MyObj.prototype = { 
    called_often: function() { 
    // lots more code than just the following 
    return 'VALUE'; //document.getElementById('someID').value; 
    }, 

    global_default: 'value', // can be changed, so need to pull value when run 

    does_stuff: function(value) { 
    var str = this.global_default + value, // can't access global_default on its own 
     input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES 
     name = this.name; // 'this' used in the prototype doesn't work 
          // even within a created object 
    return name + input + str; 
    } 
}; 

var obj = new MyObj('Bob'); 
+0

시간을내어 jsfiddle에 던져 줘서 고맙습니다! 위의 글에 대해 언급하면서, 나는이 상황에서 'this'를 사용하는 능력에 대해 혼란 스러웠다. (분명히, 프로토 타입 버전에서 "이 기능이 작동하지 않을 것"이라고 언급했기 때문에) 분명히 프로토 타입에서 이것을 사용하려고 시도했는데 오류가 발생했습니다. 이제 코드를 다시 살펴보고 내가 실제로 잘못하고있는 것을 확인해야합니다. 분명히 'this'를 사용하지 않았기 때문입니다! –

+0

이것은 훌륭한 대답입니다. – Pointy

+1

@Pointy, 감사합니다! ;) –