EML*_*EML 22 javascript closures class
我是JS的新手(来自C++ /等),我刚刚想到闭包似乎是一种比类更简单,更方便的处理封装的方法.这段代码似乎提供了一种处理封装的简单方法:
function addProperty(o) {
var value;
o["get"] = function() { return value; }
o["set"] = function(v) { value = v; }
}
// create two independent objects which are instances of pseudo-class 'addProperty',
// which each have their own version of a set of local fields, and methods that
// operate on those fields:
var a = {};
addProperty(a);
var b = {};
addProperty(b);
Run Code Online (Sandbox Code Playgroud)
如果你只是想要一个类来处理封装(在C++中,我发现这是大部分时间),有没有什么好的理由使用JS类而不是闭包?在我看来,上面的代码比JS类更直观,更紧凑.没有构造函数,原型或过度使用'this'.您还可以获得必须明确声明本地字段的好处,而不是希望您不在构造函数中进行任何拼写错误.
好的,我只是澄清一下.似乎'class'这个词得到了一些支持.无论如何,对我而言,"类"是类型概念的延伸,而JS在这方面没有资格,但我可以用我的书(Flanagan)花费50页调用类来做各种类的事情.有点.
无论如何,真正的问题是:我在我的第一个网络应用程序上使用jQuery选项卡.我昨天注意到这不起作用,因为我的JS代码没有为每个选项卡保留任何私有状态.当我在选项卡之间切换时,我的代码的动态/鼠标部分不再正常工作.
那么,将私有状态引入应用程序的最佳方法是什么?大多数代码都是安全的,但处理动态行为的所有内容都需要某种方式来封装每个选项卡的本地状态.使用C++背景,我明显的答案是编写一个定义选项卡动态部分的类,并在每次创建选项卡时实例化一个新的"选项卡"对象.我发现难以理解的是JS伪类在这里是否真的有意义,或者我是否应该扩展上面的代码.
刚刚阅读Jonathan的模块模式链接,现在在我看来可能就是答案.
谢谢.
Ray*_*nos 15
避免关闭的原因是开销.
你的get和set函数比属性慢20倍.您的闭包还有大量的内存开销,即O(N)和实例数.
另请注意,这些封装变量实际上没有任何好处,它们只是推断性能损失.
var AddProperty = {
constructor: function (v) { this._value = v; return this; },
get: function () { return this._value; },
set: function (v) { this._value = v; }
};
var a = Object.create(AddProperty).constructor(1);
var b = Object.create(AddProperty).constructor(2);
Run Code Online (Sandbox Code Playgroud)
我昨天注意到这不起作用,因为我的JS代码没有为每个选项卡保留任何私有状态.
你的问题不在于你没有私人状态,而在于你正在使用全局状态.
简单的解决方案是每个选项卡都有一个对象(如果您愿意,可以使用"结构")并在其中存储状态.
所以你要做的就是定义一个标签
var Tab = {
constructor: function (...) {
/* init state */
},
doTabStuff: function () { /* some method */ },
...
}
Run Code Online (Sandbox Code Playgroud)
然后在需要时创建新选项卡
var tab = Object.create(Tab).constructor(...)
Run Code Online (Sandbox Code Playgroud)
小智 5
为了封装功能,函数的好处是可以使用模块模式:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
模块模式提供了创建私有成员和方法的能力,没有像ease.js这样的大量开销:
这是一个古老的问题,但是仍然缺少一些答案,因此我想补充一下。
首先,正如评论者喜欢指出的那样,javascript中没有任何真正的类,我们只是使用闭包来模仿它们。这是javascript教程称为“类”的内容:
function Class1(){
var privateState='blah';
this.get=function(){
return privateState;
}
}
var myObj=new Class1();
Run Code Online (Sandbox Code Playgroud)
重要的get是,该方法只是一个闭包。因此,这基本上与您的代码相同。因为闭包必须引用创建它们的环境(这是它们可以使用私有内部状态数据的方式),所以它们比仅使用公共函数的开销更大。因此,如果您有一个不需要内部状态的静态方法,则应Class1使用prototype关键字将其添加到其中:
Class1.prototype.staticMethod=function(){...};
Run Code Online (Sandbox Code Playgroud)
这样,可以在原型链中使用静态方法,而无需使用多余的内存和不必要的闭包。您还可以通过在AddProperty函数外部添加静态方法来使用方法来实现此目的。
因此,最后,正式的javascript“类”和您的AddProperty函数之间的唯一区别是,当您实际使用类构造函数时,该类出现在对象的原型链中,而您的对象只是直接从通用object原型继承。您当然可以编写使用此区别的代码,但这可能是错误的代码。