2014-10-22 26 views
3

基本上我想要做的是爲匿名函數提供對「私人」函數/變量的訪問。我需要一些關於我實現這個方法的意見,以及可能更好的替代方法。 Fiddle在範圍之外的匿名函數中訪問「私人」成員

觀察下面的代碼片段。

function Something() 
{ 
    /*private*/ var _someVariable = 1; 

    /*private*/ function _someFunction() { 
     alert('_someFunction'); 
    } 

    /*public*/this.SomeDelegate1 = function(codeblock) { 
     var members = $.extend({ 
      _someVariable : _someVariable, 
      _someFunction:_someFunction 
     }, this);   
     codeblock.apply(members); 
    } 

    /*public*/this.SomeDelegate2 = function(codeblock) { 
     var caller = eval('(' + codeblock + ')'); 
     caller.apply(this); 
    }   

} 

在SomeDelegate1,我在我的私有成員轉換爲實例成員,並把它作爲背景的 匿名函數像下面看到的。

var someInstance = new Something(); 
someInstance.SomeDelegate1(
    function() { 
     this._someFunction(); 
     alert(this._someVariable); 
    } 
); 

我喜歡這樣一個事實,即人們可以指定您想要公開的成員,但它可能會變得非常笨重,例如,例如,當你需要更新「私有」變量時。

我明顯可以將所有成員編寫爲實例成員,但我更希望他們保持「私有」,只允許在回調函數的範圍內進行訪問。

在SomeDelegate2中,我使用了eval(是的,我意識到所有與此有關的邪惡和巫術)。

var someInstance = new Something(); 
someInstance.SomeDelegate2(
    function() { 
     _someFunction(); 
     alert(_someVariable); 
    } 
); 

因爲我把代碼注入功能,「私下」作用域成員都自動可用,所以我並不需要做的成員等,並沒有大量的工作需要進行任何複製必須做,否則。

這種方法是否存在根本問題?

你有更好的替代方案/方法來實現這一目標嗎?

+1

對我來說這似乎是一個XY問題。在JavaScript中沒有私有或公共的,我認爲在JS中用這種方式解決問題並不好。如果您使用原型和前綴屬性,那麼您將在性能和API中獲得更多優勢,而前綴屬性並非意味着像下面這樣以下劃線來觸及下劃線。 – elclanrs 2014-10-22 07:42:34

+0

意識到這一點,所以我把私人話題放在引號中),但是他們的工作方式也是類似的。 – cstruter 2014-10-22 07:43:43

+2

不這樣說。但是,儘管它們的工作方式類似,但不使用原型,每次創建新實例時都會創建這些函數。而且,你不能使用沒有實例的函數。 – elclanrs 2014-10-22 07:48:10

回答

1

正如我在我的評論中所說的,我會公開所有內容並以「下劃線」爲前綴「private」屬性名稱。這是我會怎麼調整你的代碼:

function defclass(prototype) { 
 
    var constructor = prototype.constructor; 
 
    constructor.prototype = prototype; 
 
    return constructor; 
 
} 
 

 
var Something = defclass({ 
 
    constructor: function() { 
 
     this._someVariable = 1; 
 
    }, 
 
    _someFunction: function() { 
 
     alert("someFunction"); 
 
    }, 
 
    someDelegate1: function (f) { 
 
     f.apply(this); 
 
    }, 
 
    someDelegate2: function (f) { 
 
     f.call(this, this._someVariable, this._someFunction); 
 
    } 
 
}); 
 

 
var someInstance = new Something; 
 

 
someInstance.someDelegate1(function() { 
 
    this._someFunction(); 
 
    alert(this._someVariable); 
 
}); 
 

 
someInstance.someDelegate2(function (someVariable, someFunction) { 
 
    someFunction(); 
 
    alert(someVariable); 
 
});

不過這只是我的看法。我真的沒有看到擁有私有變量的觀點。即使有人用你的私有變量混淆,這是他們的問題,而不是你的問題。它會破壞他們的代碼,而不是你的代碼。

+0

我想它只是從我使用的其他編程語言中產生的一個問題,因爲它的某些東西可以在JS中避免使用(使用範圍)。 這些方法最大的問題僅僅是一個指導方針等。 您沒有看到C#或PHP開發人員將所有成員都標記爲公開嗎? – cstruter 2014-10-22 08:34:14

+0

我不使用C#或PHP,但我使用C,而在C中我們也沒有任何「私有」屬性。 「私人」和「公共」財產的整個概念(以我的愚見)是膚淺的。你的房產是私人的還是公共的並不重要。想想這個問題:Linux內核是使用C(和一些程序集)構建的。如果一個流行的操作系統內核不需要私有屬性,那麼爲什麼你呢?擁有私人財產有什麼好處?如果你真的想防守編程,那麼爲什麼不把所有東西都變成不變的,並使用函數式編程語言呢?問題不存在 – 2014-10-22 08:38:48

+0

封裝是面向對象的支柱之一,可以說爲什麼我們真的需要面向對象等,但是在這件事上有很多相關的材料,我認爲對你而言是一種不同的思想流派;) – cstruter 2014-10-22 08:43:27