[英]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.