2014-10-22 29 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