JavaScript 中有没有办法在原型私有(使用模块 JS 模式)方法中提供对变量的访问
Is there a way in javascript to give access to variable inside a prototype private (using the Module JS Pattern) method
假设这段代码是javascript代码
(function(){
NameSpace = new function(){} //global namespace
NameSpace.Apple = function(p_color){
var AppleInstance = this; //clarity..
AppleInstance.color = p_color;
return {
/**************
/ Public method
/**************/
//Here, we only return an access to the Method Eat
Eat : NameSpace.Apple.prototype.Eat
}
}
//Will be public
NameSpace.Apple.prototype.Eat = function(){
var AppleInstance = this; //clarity..
console.log("I'm eating a " + AppleInstance.color + " apple !")
}
//Will be private
NameSpace.Apple.prototype.PrivateMethod = function(){
var AppleInstance = this; //clarity..
console.log("This is a private method");
}
})()
new NameSpace.Apple("blue").Eat();
//I'm eating a undefined apple !
如您所见,我在命名空间中有一个类,其中包含 1 个私有变量、1 个私有方法和 1 个公共方法。但是当访问我的公共方法时,这个方法无法访问类的变量。
我知道这是因为:
return {
/*...*/
}
但是有没有办法让我的公共原型方法访问我的私有变量(在我的原始代码中,我想要一个常量......(,而不通过返回来访问它。
如果我在返回中返回属性,原型方法将可以访问它,但不能访问它。
谢谢。
不。 这两种策略有些不相容。 这就是为什么私有属性通常是公共的,但在使用原型时带有下划线。
Namespace.Apple = function(p_color){
this._color = p_color;
};
Namespace.Apple.prototype.eat = function(){
console.log("I'm eating a " + this._color + " apple !")
};
这告诉使用此代码的 JS 开发人员,他们不应该弄乱 _color
属性,因为它是供内部使用的。
也就是说,你在这里还有其他大问题......
Namespace.Apple = function(p_color){
var AppleInstance = this; //clarity..
AppleInstance.color = p_color;
return {
/**************
/ Public method
/**************/
//Here, we only return an access to the Method Eat
Eat : NameSpace.Apple.prototype.Eat
}
}
这不符合您的想法。当构造函数返回对象时,使用 new
创建的实例将被丢弃。 因此,您最终不会得到Apple
的实例。相反,你会得到一个普通对象,如下所示:
{ Eat: Namespace.Apple.prototype.Eat }
那么,您为其分配了颜色的对象?不见了。
此方法不是专用的。
//Will NOT be private
Namespace.Apple.prototype.PrivateMethod = function(){
var AppleInstance = this; //clarity..
console.log("This is a private method");
}
原型上的所有内容都是公开的。万事。
还有关于约定的说明。
var AppleInstance = this; //clarity..
我认为根本不清楚。 this
在实例方法中用于表示this
实例。 任何混淆都会损害可读性。
并且,请保存构造函数的大写字母变量名称(Eat
糟糕!,Apple
好!,AppleInstance
糟糕!(,也为了可读性。因为调用没有 new
关键字的构造函数可能会产生一些奇怪的后果。
为了避免这种情况,并且仍然有私有变量和方法,你根本不使用原型。 您将所有变量和方法设置为构造函数中的函数,逐段构建实例。
var Namespace = {};
Namespace.Apple = function(color){
// color form the arguments is a local variable, bound to the methods created below
var somePrivateVar = 'privateData!'; // private instance variable
// public method, with access to private instance vars
this.eat = function(){
console.log("I'm eating a " + color + " apple!");
};
// public method, which calls private method
this.doSomethingPrivate = function() {
console.log('calling private method for you');
privateMethod()
}
// private method
var privateMethod = function(){
console.log("This is a private method for a " + color + " apple!");
};
// instance is auto-returned, no return needed.
}
var apple = new Namespace.Apple('red');
apple.eat(); // I'm eating a red apple!
apple.doSomethingPrivate(); // calling private method for you
// This is a private method for a red apple!
apple.privateMethod() // <exception> apple.privateMethod is undefined
关于这种方法,唯一需要注意的是,与使用原型相比,它可能慢得多,并且使用更多的内存。原型上的函数在所有实例之间共享,因此您只需为方法创建和存储单个函数,每个实例都将执行该函数对象。
使用上述方法,每个实例都会创建并存储每个方法函数的新副本。每个函数都有权访问该实例构造函数的范围,从而允许您使用私有变量和方法。 如果您只计划有几个实例,则此差异可能不会产生太大差异。但是,如果您计划拥有大量实例,则性能差异可能变得非常重要。
要实现封装,建议您使用以下结构:
(function(){
NameSpace = new function(){} //global namespace
NameSpace.Apple = function(p_color){
var AppleInstance = this; //clarity..
var color;
AppleInstance.color = p_color;
this.Eat = function(){
/**************
/ Public method
/**************/
//Here, we only return an access to the Method Eat
alert("I'm eating a " + AppleInstance.color + " apple !")
}
//Will be private
var private = function(){
var AppleInstance = this; //clarity..
alert("This is a private method");
}
function constructor(p_color){
AppleInstance.color = p_color;
}
constructor(p_color)
}
})()
new NameSpace.Apple("blue").Eat();
//I'm eating a blue apple !
new NameSpace.Apple("blue").private();
// Exception raised
我从不赞成忽略本地副本的this
变量,它对 JS 对象的调用结构中的范围具有重要意义,并为开发人员提供了有关这些可能在哪里更改的线索。
顺便说一句:Namespace.Apple.prototype.PrivateMethod
不会是一个私有方法,因为通过原型公开的所有内容都是公开的。
- 有没有一种方法可以防止img get请求使用css或js发生
- 有条件更新d3.js力图中节点的最佳方法
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- 有没有任何方法可以使用node-js从不同的机器打开浏览器
- 有没有比在app.js上绑定模块名称更好的方法来动态加载视图模型和视图以显示模态
- 有没有一种方法可以获得three.js的最小/lite版本
- Underscore.js某些对象的所有方法的总和
- node.js是否具有'match()'方法如果是,语法是什么
- 当数据库中的某些内容发生变化时调用HTTP方法Meteor.js
- 当用户点击动态创建的链接时,如何调用JS方法.JQuery,ASP.NET MVC
- 从React调用方法.JS州
- 从方法js中的函数获取对象属性
- 是否可以在 Vue 中嵌套方法.js以便对相关方法进行分组
- 主干 - 从我的原型视图调用方法.js
- $(这个).方法(js 或 jquery)
- 如何在噩梦中运行多种评估方法.js
- 如何从骨干中的集合调用模型的方法.js
- 如何在传单中使用 .off() 事件方法.js
- 检查这个的好方法和干净的方法?(JS+HTML)
- 使用爆米花迭代提示方法.js