在 JavaScript 中,我可以通过在构造函数中声明它们来创建私有和特权方法。通过这个,我必须将它们移出对象的原型。然后我失去了继承的可能性和一些性能,因为每个对象都将拥有这些方法的自己的副本,而不是访问一个原型对象。
所以我现在的问题是什么可能是一个petter模式:是否使用私有和特权方法。我不喜欢晃来晃去,所以我想避免这种情况。那么该怎么办?
你有什么经验?
在 JavaScript 中,我可以通过在构造函数中声明它们来创建私有和特权方法。通过这个,我必须将它们移出对象的原型。然后我失去了继承的可能性和一些性能,因为每个对象都将拥有这些方法的自己的副本,而不是访问一个原型对象。
所以我现在的问题是什么可能是一个petter模式:是否使用私有和特权方法。我不喜欢晃来晃去,所以我想避免这种情况。那么该怎么办?
你有什么经验?
我从未见过在 JavaScript 中创建所谓的“私有”函数的任何价值。只需以某种方式标记它们以表明它们不是您的公共 API 的一部分,因此 API 客户端不能保证该函数将存在,或者在未来的版本中具有相同的实现。
除了 API 的一致性,没有理由不让人们只使用你的私有函数,如果他们愿意的话。当然,它允许共存脚本与您的私有函数混淆,但无论如何,这些脚本可能已经覆盖了您的公共 API 函数。
这个问题的公认答案对此有很好的评论: Private functions in namespaced javascript
约定是限定需要的范围......并让伪私有或受保护成员在您的方法或属性前加上下划线。
我更喜欢伪私有/受保护范围...
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 的功能性事件驱动性质。
您可以使用模拟私有或内部方法和属性
obj._foo = private;
obj.prototype._internalMethod;
您需要将私有方法与继承分开。任何可以在不依赖继承的情况下使用的东西都可以正常工作。还有这样的模式:
function construct() {
var priv;
this.someValue = foo;
this.someMethod = function() { }
}
这里我们忽略原型,直接写入对象。这种依赖闭包来隐藏方法和变量的模式适用于 mixin。
担心在构造函数中重新声明方法是否效率低下是一种微优化和邪恶。如果您不希望创建至少 1000 个对象,则差异可以忽略不计。
我只是猜测你有一些在构造函数中使用的函数,但不是公共 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
,但此类检查根本不安全,并且不提供对实际私有成员的保护。
我认为这完全取决于你想如何使用你的对象。如果您需要某个对象中的私有变量/函数,并且希望它们可以被该对象的原型方法访问,那么您必须顺便在构造函数中声明原型方法(请参见此处的示例)。
在我看来,它归结为程序的设计和使用。如果您需要具有真正私有变量或 - 函数的对象,请按照我给出的示例进行设计,否则不要。以我的经验,私有/特权功能并没有真正影响性能。
在创建 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); }; };
注意事项:
希望这可以帮助。
(function () {
function privateFunc () { ... }
A.prototype.publicFunc1 = function () { ... };
A.prototype.publicFunc2 = function () { ... };
})();
function A () { ... }
我编辑:如果您还想要私有变量,这无济于事。