Javascript-闭包-语法-公共成员
Javascript - closure - syntax - public members
我已经读了很多关于闭包和原型的文章。。。但我还有一些问题。我从这篇文章开始:http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx
我的问题是关于公开公共方法:
这种方法是吗
// Closure implementation
function Pixel(x, y){
this.x = x;
this.y = y;
this.getX = function(){
return this.x;
}
this.getY = function(){
return this.y;
}
this.setX = function(value){
this.x = value;
}
this.setY = function(value){
this.y = value;
}
}
与此不同:
// Closure implementation
function Pixel(x, y){
this.x = x;
this.y = y;
return {
getX : function(){
return this.x;
},
getY : function(){
return this.y;
},
setX : function(value){
this.x = value;
},
setY : function(value){
this.y = value;
}
}
}
哪一个是最好的?为什么?
最后一个问题:从上面的基准来看,有没有一种方法可以使用闭包来获得与原型类似的性能?
tx
没有"更好"的实现了。
第二个选项将产生错误,因为您无法对其调用new,因此this
将引用窗口(或定义/调用函数时您所在的任何范围),因此不要使用它
第二种选择可以使用这样的闭包:
function Pixel(x, y){
this.x = x;
this.y = y;
var that = this;
return {
getX : function(){
return that.x;
},
getY : function(){
return that.y;
},
setX : function(value){
that.x = value;
},
setY : function(value){
that.y = value;
}
}
}
但这开始变得非常丑陋,与prototype
不兼容,并且在我看来过于重视隐私问题。
有很多话要说。首先,这种get
/set
机制在Javascript中很少适用。这个Java构造与确保所有对数据的访问都是通过公共方法,而不是通过私人财产;Javascript世界根本不在乎。
但是,假设您确实想要Pixel对象,并且希望封装它们的x
和y
数据,例如,暴露以下两个函数:
toString(); // String (a representation of this Pixel)
offset(deltaX, deltaY); // Pixel (a new Pixel shifted by deltas from this one)
然后你可以这样做:
var PixelA = function(x, y) {
this.x = x; this.y = y;
this.toString = function() {
return "(" + this.x + ", " + this.y + ")";
};
this.offset = function(deltaX, deltaY) {
return new PixelA(this.x + deltaX, this.y + deltaY);
};
};
或者你可以这样做:
var PixelB = function(x, y) {
this.toString = function() {
return "(" + x + ", " + y + ")";
};
this.offset = function(deltaX, deltaY) {
return new PixelB(x + deltaX, y + deltaY);
};
};
或者你可以这样做:
var PixelC = function(x, y) {
this.x = x; this.y = y;
}
PixelC.prototype.toString = function() {
return "(" + this.x + ", " + this.y + ")";
};
PixelC.prototype.offset = function(deltaX, deltaY) {
return new PixelC(this.x + deltaX, this.y + deltaY);
};
(注意:所有都未经测试。)
PixelA
相当天真。我们的数据没有封装;任何人都可以直接访问或更改我们的内部x
和y
属性。而且它是记忆密集型的;PixelA的每个实例都将具有CCD_ 10和CCD_。
PixelB
解决了第一个问题。内部数据存储在构造函数生成的闭包中。toString
和offset
函数可以访问这些变量,但外部没有任何东西可以直接看到它们。但这并不能缓解第二个问题。
CCD_ 15解决了第二个问题。由于toString
和offset
函数存储在原型上,因此实例中没有它们的重复副本。但是x
和y
属性再次公开,第一个问题又回来了。
我不知道选项D。我认为您需要在封装内部状态和允许原型函数访问该状态之间做出选择。你可以通过许多不同的策略扭曲来尝试解决这个问题;但没有一个真正解决这个根本问题。您可以在任一方向执行某些优化,但问题是根本性的。
我希望被证明是错的。
至于性能问题:基于闭包的构造不可能像基于原型的构造那样快。想想在基于闭包的版本中为每个实例分配所有这些属性所需要做的所有工作,在基于原型的版本中根本不需要做这些工作。现在,基于闭包的属性访问可能会更快。。。
- 铬:“;未捕获的语法错误:意外的标记:"
- jQuery语法添加了var
- Javascript未捕获语法错误意外的标识符错误
- 为什么忽略了eval()代码中的语法错误
- 难以访问的JS环境中的语法错误
- 如何告诉MathJax对下标使用替代语法
- Javascript语法向设置发出sessionStorage值
- 未捕获的语法错误:意外的标记{
- 使用$scope方法时的ControllerAs语法
- "未捕获的语法错误:意外的标记}"
- javascript自执行函数-不同的语法
- 函数的Javascript语法
- WinJS内联绑定语法
- 使用JS函数来使用另一个函数的语法?node.js
- 未捕获的语法错误:无法在“文档”上执行“查询选择器”
- 更新成员数据模型中的记录列表
- 有没有针对带有表的JavaScript的Markdown语法解析器
- 我需要使用什么语法来向一个对象的成员添加一个临时数组,该成员等同于一个字符串的通用列表
- JavaScript类语法:静态数据成员
- Javascript-闭包-语法-公共成员