簡體   English   中英

如何封裝對象屬性,以便不接管以前的對象? (原型/關閉)。

[英]How can I encapsulate object property so that previous object isn't taken over? (Prototypes/closure.)

我開始着手在Javascript中進行原型設計和閉包,但是還不完全如此。 下面的示例是我的兩個對象,第二個對象似乎失去了作用域/上下文,並接管了第一個對象的身份。

function broker()
{
    var _q = [];
    this.add = function(delegate) {_q[_q.length] = delegate; }
    this.broadcast = function(message)
    {
        for(qi = 0; qi < _q.length; qi++)
        {
            _q[qi](message);
        }
    }
}

function subscriber(abroker, yourname)
{
    me = this;
    this.myprop = yourname;
    this.subby = function(message){ alert(message + " " + me.myprop + me.dosomething() + secret()); };
    this.dosomething = function() {return "...abc";};
    function secret(){return "...def";}

    abroker.add(this.subby);
}

var thebroker = new broker();
var mysub = new subscriber(thebroker, 'mysub');
var myothersub = new subscriber(thebroker, 'myothersub');
thebroker.broadcast("hello from");

這個想法是,有一個公共代理對象可以調用訂戶對象上的委托並執行其中的功能。 但是我正在失去經紀人調用的調用函數的作用域。

輸出: 2個警報窗口,都輸出:“ myothersub”,mysub似乎失去作用域?

通過在原始對象之外顯式聲明subby委托並引用整個對象,我已經成功實現了正確的響應,例如:

而不是在訂戶對象中聲明this.subby:

mysub.subby = function(message)
{
    alert(message + " " + mysub.myprop); // obv the dosomething his hidden
}

thebroker.add(mysub.subby);

如果上述任何語法有誤,請直接從內存中鍵入。 它確實可以在實踐中工作,但是會丟失我慣用的封裝。

如何在丟失對象范圍/上下文的情況下使用原始技術封裝?

簡短的回答:看來問題似乎與您在subscriber構造函數中對me的聲明有關。 至少需要在其前面放置一個var ,以使其成為每個對象的本地/私有變量。 所以var me = this; 代替me = this;

說明:在JavaScript中,當您未使用var顯式聲明變量時,它將使該變量成為全局變量。 因此,原始腳本中發生的事情是您創建了mysub ,該聲明將me聲明為mysub對象內部this的全局引用。 但是,一旦創建了myothersub ,全局對象me被新myothersub對象中的this覆蓋。

因為你的subby方法創建基於警報me這並不重要,哪個對象是不使用任何本地或特定的對象,而只是引用相同的全局變量從因為在這兩種對象的方法中調用它- this在最后一個要創建的對象中

通過簡單地寫var me = this; 代替me = this; 您每次在閉合中為創建的每個新對象創建一個本地版本的me ,而不是被覆蓋的對象。

...

PS。 額外提示。 您應該對所有變量進行此操作,以確保您擁有盡可能少的全局變量,尤其是當您不希望它們成為全局變量時! 因此,我將對broker構造函數中的變量qi進行相同的聲明。 您只需在循環條件內聲明條件即可,例如for (var qi = 0; qi < _q.length; qi++) 這足以阻止qi成為全局變量。

但是,為了使代碼易於閱讀,最好在函數頂部聲明所有變量。 因此,我建議您簡單地重寫broadcast方法,如下所示:

this.broadcast = function(message) {
    var qi,             // STOPS `qi` BECOMING A GLOBAL
        ql = q.length;  // SO DON'T HAVE TO CHECK LENGTH OF `q` EVERY LOOP
    for(qi = 0; qi < ql; qi += 1) {
        _q[qi](message);
    }
};

如果您以前從未遇到過,Douglas Crockford是JavaScript的非常好的入門作家,涉及到閉包,對象創建以及良好的代碼編寫約定。 此頁面上有很多技巧,您可以輕松找到他講授該主題的視頻。 當我開始更仔細地研究閉包和JavaScript的其他方面時,所有這些都對我有所幫助。 希望對您有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM