在JavaScript中,我可以通过在构造函数中声明它们来创建私有和特权方法。通过这个我必须将它们移出对象的原型。然后我失去了继承和一些性能的可能性,因为每个对象都拥有它自己的那些方法的副本,而不是访问一个原型对象。
所以现在我的问题是什么可能是一个小小的模式:是否使用私有和特权方法。我不喜欢晃来晃去,所以我想避免这种情况。那该怎么办?
您有什么经历?
答案 0 :(得分:5)
我从未在JavaScript中创建所谓的“私有”函数。只需标记它们以表明它们不属于您的公共API,因此API客户端无法保证该函数将存在,或者在将来的版本中具有相同的实现。
除了API一致性之外,没有理由不让人们只使用你的私人功能。当然,它允许共存脚本与您的私有函数混合,但无论如何,这些脚本可能已经覆盖了您的公共API函数。
这个问题的公认答案对此有很好的评论: Private functions in namespaced javascript
答案 1 :(得分:4)
惯例将是范围内所需要的...以及伪造的私有或受保护成员为您的方法或属性添加下划线的前缀。
我更喜欢伪造的私人/受保护范围......
var MyObject = (function(){
var interalStaticVar;
function ctor(arg1, arg2) {
//create psuedo-protected context
this._ = {};
//create a psuedo-private context
this.__ = {};
//stash someval
this.__.someVal = "hands off";
}
ctor.prototype.getSomethingPrivate = function() {
return this.__.someVal;
}
ctor.prototype._doSomethingProtected = function(){ ... }
ctor.prototype.__doSomethingPrivate = function() { ... }
return ctor;
}());
我会说尝试将OO风格的继承范例应用于JavaScript是在寻找麻烦,可能意味着你做错了什么。我倾向于在浏览器中遵循更多SOLID设计,包含JS的功能事件驱动特性。
答案 2 :(得分:3)
您可以使用
模拟私有或内部方法和属性obj._foo = private;
obj.prototype._internalMethod;
您需要将自己的私有方法与继承分开。任何可以在不依赖继承的情况下使用的东西都可以正常工作。还有这样的模式:
function construct() {
var priv;
this.someValue = foo;
this.someMethod = function() { }
}
这里我们忽略原型并直接写入对象。这种依赖闭包隐藏方法和变量的模式适用于mixin。
担心在构造函数中重新声明方法是否效率低是微优化和 evil 。如果您不希望创建至少1000个对象,则差异可以忽略不计。
答案 3 :(得分:3)
我只是猜测你有一些在构造函数中使用的函数,但它们不是公共API的一部分。
在这种情况下,一个选项是将它们作为属性存储在构造函数中。然后在构造函数中调用它们时,您将使用.call()
方法设置正在构造的当前对象的上下文。
这样,您可以通过this
自动访问公共成员,如果您将其作为参数传递,则可以自动访问私有变量。
var myClass = function() {
this.someprop = 'prop value';
var privVar = 'private value';
myClass.func.call(this, privVar);
};
myClass.func = function(priv){
alert(this.someprop);
alert(priv);
};
var inst = new myClass;
因此,这只是将MyClass
函数用作构造函数使用的函数的命名空间存储。构造函数从this
的上下文中调用它,它使用this.someProperty
和传入的privVar
执行某些操作。
不确定这是否是你所追求的,但这是一个选择。
正如@Raynos在下面的注释中正确指出的那样,作为简单命名空间存储添加到MyClass
构造函数的任何属性都不是私有的,并且可以由任何可以访问构造函数的代码访问
您可以进行一些检查以帮助确保正确调用它,例如添加instanceof
检查以确保从MyClass
的实例调用它,但此类检查根本不是安全的不提供实际私人会员的保护。
答案 4 :(得分:2)
我认为这一切都取决于你想如何使用你的对象。如果在某个对象中需要私有变量/函数,和希望它们可以被该对象的原型方法访问,则必须在构造函数中声明原型方法(顺便提一下example here)。
在我看来,它归结为程序的设计和使用。如果您需要具有真正私有变量或 - 函数的对象,请将其设计为我给出的示例,否则不要。根据我的经验,私有/特权功能并没有真正影响性能。
答案 5 :(得分:0)
创建javascript对象时,我通常会遵循以下模式。
var builders = (function() {
var privateMethod = null;
function builders() {
this.a_priviledged_method = function() {};
this.pointerToPrototypeMethod = __bind(this.prototypeMethod, this);
}
builders.prototype.prototypeMethod = function(){};
return builders;
})();
// general method to bind a function call to a context
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
注意事项:
希望这有帮助。
答案 6 :(得分:-1)
(function () {
function privateFunc () { ... }
A.prototype.publicFunc1 = function () { ... };
A.prototype.publicFunc2 = function () { ... };
})();
function A () { ... }
我编辑:如果您还想要私有变量,这无济于事。