javaScript对象的属性是由名字、值和一组特性组成的。在ECMAScript5中,属性的值可以由一个或两个方法替代,这两个方法就是getter和setter。由getter和setter定义的属性称为“存取器属性”,它不同于“数据属性”,数据属性只有一个简单的值。
当程序查询存取器属性的值时,Javascript调用getter方法(无参数)。这个方法返回的值就是属性存取表达式的值。当程序设置一个存取器属性的值时,JavaScript调用setter方法,将赋值表达式右侧的值当做参数传入setter。从某种意义上讲,这个方法负责“设置”属性值。可以忽略setter方法的返回值。
和数据属性不同,存取器属性不具有可写性。如果属性同时具有getter和setter方法,那么它是一个读/写属性。如果它只有getter方法,那么它是一个只读属性。如果它只有setter方法,那么它是一个只写属性(数据属性中有一些例外),读取只写属性总是返回undefined。
定义存取器属性最简单的一种方法是使用对象直接量语法的一种扩展写法:
var o = { //普通的数据属性 data_PRop: value, //存取器属性都是成对定义的函数 get accessor_prop(){/*这里是函数体*/}, set accessor_prop(value){/*这里是函数体*/}};存取器属性定义为一个或两个和属性同名的函数,这个函数定义没有使用function关键字,而是使用get和set。注意这里没有使用冒号将属性名和函数体分开,但在函数体的结束和下一个方法或数据属性之间有逗号分隔。例如,思考下面这个表示2D笛卡尔点坐标的对象,它有两个普通的属性x和y分别表示对应点的X坐标和Y坐标,它还有两个等价的存取器属性用来表示点的极坐标:var p = { //x和y是普通的可读写的数据属性 x: 1.0, y: 1.0, //r是可读写的存取器属性,它有getter和setter。 //函数体结束之后不要忘记带上逗号 get r(){ return Math.sqrt(this.x * this.x + this.y * this.y); }, set r(newValue){ var oldValue = Math.sqrt(this.x * this.x + this.y * this.y); var ratio = newValue / oldValue; this.x *= ratio; this.y *= ratio; }, //theta是只读存取器属性,它只有getter方法 get theta(){ return Math.atan2(this.y, this.x);}};注意这段代码里面getter和setter使用了this关键字。在函数体内的this指向表示这个点的对象,因此r属性的getter方法可以通过this.x和this.y来引用x属性和y属性。
和数据属性一样,存取器属性是可以继承的。因此可以将上述代码中的对象p当做另一个点的原型。
在ECMAScript5标准被采纳之前,大多数JavaScript的实现已经可以支持对象直接量语法中的get和set写法。这些实现提供了非标准的老式API用来查询和设置getter和setter。这些API由4个方法组成,所有对象都拥有这些方法。__lookupGetter__()和__lookupSetter__()用以返回一个命名属性的getter和setter方法。__defineGetter__()和__defineSetter__()用以定义getter和setter,这两个函数的第一个参数是属性名字,第二个参数是getter和setter方法。这4个方法都是以两条下划线作为前缀,两条下划线作为后缀,以表明它们是非标准的方法。
新闻热点
疑难解答