Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 简洁的替代品?_Javascript_Getter Setter - Fatal编程技术网

Javascript 简洁的替代品?

Javascript 简洁的替代品?,javascript,getter-setter,Javascript,Getter Setter,在VB.Net中,getter和setter是一种美: Get Return width End Get Set(ByVal value As Integer) width = value End Set 在Javascript中,我们可能会这样做: function Test() { var width = 100; this.__defineGetter__("Width", function() { return width; })

在VB.Net中,getter和setter是一种美:

Get
    Return width
End Get
Set(ByVal value As Integer)
    width = value
End Set
在Javascript中,我们可能会这样做:

function Test() {
    var width = 100;
    this.__defineGetter__("Width", function() {
        return width;
    });
    this.__defineSetter__("Width", function(value){
        width = value;
    });
}
它看起来像一盘意大利面被一个库里人洗劫过。我们有哪些更整洁的选择


注意:新代码应使用
new Test().Width
访问值,而不是
new Test().Width()
使用ES5,您可以执行以下操作:

function Test() {
  var a = 1;

  return {
    get A() { return a; },
    set A(v) { a = v; }
  };
}
当然,getter/setter函数可以执行您希望它们执行的任何操作。

这里有一个干净(er)的替代方法(也适用于较旧的脚本引擎):

请注意,您不能使用它来定义私有/静态复杂结构。使用此模式只能“获取”字符串或数字(因此变量是不可变的)。也许可以使用json增强模式

[edit]使用json,还可以通过这种方式为对象创建getter:

function Test() {
  var a=1,
  b = {foo:50, bar:100};

  return { 
          A: { toString: function(){return a;} } 
          foobar: { toString: function(){return JSON.stringify(b);}  } 
         };
}
var foobar = JSON.parse(Test().foobar);
alert(foobar.foo); //=> 50

在ECMAScript 5中,“干净”(且符合标准)的方法是使用defineProperty

function Test() {
    var a = 1;
    Object.defineProperty(this, "A", {get : function() { 
            return a;
        },  
        enumerable : true});
}
这假设您只想了解如何定义getter。如果您只想使Test的实例不可变(如果可以的话,这是一件好事),那么应该使用freeze:

function Test() {
    this.a = 1;
    Object.freeze(this);
}

顺便说一句,我需要一个“getter”,因为不是返回一个;我们可以假设类似于f()的东西;返回a;这个问题和你以前的问题有什么不同?根据你的另一个问题,“a”不是应该被“测试”的所有实例共享吗?@Alnitak,问题是无关的。@Chandu,Alnitak刚刚回答了你的问题。.这会占用内存,因为每个对象的getter和setter都是“唯一的”。另外,当在构造函数中返回表达式时,您不能对原型执行任何操作。@TylerCrompton是的,这绝对正确;我只是按照原来问题的提纲。如果可能的话,最好在原型上有getter/setter。这里可以找到不同getter和setter(包括一个实时基准测试)的一个很好的概述:我非常确定您所描述的只是firefox的扩展。ecmascript5语法有点不同,它使用对象方法。@kybernetikos我不太确定,这种语法在使用V8的Node.JS中有效。这(就像接受的答案一样)不占用内存吗?我对js很陌生,但在我看来,这些getter/setter属于原型。建议在
Test
函数之后说
Object.defineProperty(Test.prototype,“A”,{get:function(){…}})
应该是可能的。那不是“更干净”吗?是的,你完全正确。我这样做是为了更像他在问题中的示例代码,但通常我希望在可能的情况下将东西放在原型上,我可能应该指出这一点。当然,另一个因素是,如果你这样做,你必须将实际值放在“this”上,这意味着你失去了信息隐藏方面,这一直是一个耻辱。@kybernetikos,那么你是说Pointy的答案不符合标准吗?我可能错了,但据我所知,拥有原型上的属性不会阻止对象的实例获取其同名属性,这将模糊原型上的属性。如果原型上有一个具有setter的属性,则执行
child.propertyname=someValue
将导致调用setter,不覆盖propertyname。但是,您可以正确地说,您仍然可以在子级上使用Object.defineProperty重写该属性。为什么使用
A:{toString:function(){return A;}}}
和`foobar:{toString:function(){return JSON.stringify(b);}}`而不是简单地使用
A:return A
foobar:return JSON.stringify(b)
?@Pacerier他依赖于一些函数(例如
alert
)的默认行为,这些函数会自动调用
.toString()
,对任何还不是字符串的参数进行调用。@Alnitak,是的,为什么不直接返回
a
,而不是通过toString返回
a
的对象?我是说有什么区别。。。为什么不直接返回
a
function Test() {
    this.a = 1;
    Object.freeze(this);
}