TMS*_*TMS 9 javascript oop closures
我目前正在用javascript编写对象,我想用一种清晰,好的方式,使用最佳实践等来做这件事.但是我很担心我必须总是写this.地址属性,这与其他OO语言不同.
所以我明白了 - 为什么不只是使用闭包来获取对象属性?看看我的示例对象.所以不是这样,经典方式:
var MyObjConstructor = function (a, b) {
// constructor - initialization of object attributes
this.a = a;
this.b = b;
this.var1 = 0;
this.var2 = "hello";
this.var3 = [1, 2, 3];
// methods
this.method1 = function () {
return this.var3[this.var1] + this.var2;
// terrible - I must always write "this." ...
};
}
Run Code Online (Sandbox Code Playgroud)
...我会使用闭包这样做,然后我不需要this.每次都写入访问属性!
var MyObjConstructor = function (a, b) {
// constructor - initialization of object attributes
// the attributes are in the closure!!!
var a = a;
var b = b;
var var1 = 0;
var var2 = "hello";
var var3 = [1, 2, 3];
// methods
this.method1 = function () {
return var3[var1] + var2;
// nice and short
};
// I can also have "get" and "set" methods:
this.getVar1 = function () { return var1; }
this.setVar1 = function (value) { var1 = value; }
}
Run Code Online (Sandbox Code Playgroud)
此外,它还有一个隐藏的好处,即除了get/set方法之外,其他任何方式都无法访问这些属性!
95%的性能下降.
一个实际的基准测试,所以对于你的(简单)例子,浏览器的性能下降了50%-85%.
说真的,闭包很慢.
现在使用闭包数据不是问题,但是使用函数/方法的闭包是.如果没有另一个,你就无法做到.生活在原型上的方法没有访问构造函数内部的局部变量的机制.
而另一个问题是你的"经典"例子没有使用原型:
你真正想要的是什么
所以以下也不好.
var MyObjConstructor = function (a, b) {
// constructor - initialization of object attributes
this.a = a;
this.b = b;
this.var1 = 0;
this.var2 = "hello";
this.var3 = [1, 2, 3];
// methods
this.method1 = function () {
return this.var3[this.var1] + this.var2;
};
}
Run Code Online (Sandbox Code Playgroud)
你要
// constructor - initialization of object attributes
var MyObjConstructor = function (a, b) {
this.a = a;
this.b = b;
}
Object.extend(MyObjConstructor.prototype, {
var1: 0,
var2: "hello",
var3: [1, 2, 3],
// methods
method1: function () {
return this.var3[this.var1] + this.var2;
}
});
Run Code Online (Sandbox Code Playgroud)
对于Object.extend的某些值.以下是在原型上放置任何常见数据或方法,并在所有实例之间共享该数据.这样我们就无法随时随地记录所有内容.
//太糟糕了 - 我必须写"这个"....
另一种方法是复制每个对象的状态.闭合模式很好,除了它之外它不是很好.
直接回答您的问题:
1. 使用对象作为闭包可以吗?它符合最佳实践吗?
是的。在某些情况下,您确实希望拥有私有字段,因此这是实现这一目标的唯一方法之一。对于真实、具体的示例,请查看 Dojo 或 JQuery 中的 Deferreds/Promises。Promise 只实现了 deferred 的非变异子集,因此它们需要保持内部 Deferred 的私有性,以避免其他人直接更改它。
请记住,您应该只在真正需要的地方使用隐藏字段(而不是出于诸如不必键入“this”之类的琐碎原因)。使用普通的旧公共字段和“普通”对象也完全没问题,特别是如果您认为它们具有闭包版本所没有的一些优点:
2. 这两个版本之间有语义差异吗?
是的。
3、使用这样的闭包有没有什么陷阱?
与使用原型的代码相比,当今大多数 Javascript 引擎在具有大量闭包的代码上的性能较差。这并不是造成差异的“真正”原因(因为 LISP 引擎一直以来都可以很好地处理闭包),但这是您必须忍受的。
| 归档时间: |
|
| 查看次数: |
729 次 |
| 最近记录: |