2012-06-06 56 views
21

實現以下(不起作用)的最佳設計模式是什麼?Javascript:調用該對象中的對象方法

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

嘛,從你的第一個例子:

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

這是什麼this值是。

現在,您不能做的是從對象字面量語法的其他地方引用「正在建設中」對象的屬性。 (很難舉一個例子,因爲它在語法上不可能。)如果你想這樣做,你確實需要一個或多個單獨的賦值語句。

+0

我以爲'this'只是指向對象,如果它是用new +構造函數創建的,或者如果您使用call/apply。但你是對的,它的工作原理!顯然,我一直在困惑。另外,我原以爲我試過了。但顯然不是。 –

+0

在同一時間,JavaScript非常簡單並且非常複雜:-)事實證明,當某個函數被調用時,this被綁定,那就是這個;然而,這條簡單的規則導致了各種有趣的細節。 – Pointy

+0

嗨,波蒂。我有同樣類型的問題。我正在使用'roundslider.js',並且我正在調用一個函數,在這裏你寫了一些東西。但對我來說這是錯誤的。 $(「#slider」)。roundSlider({function(event){ 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

@積分,謝謝! ;) –