JavaScript 中的 Getter 和 Setter
概述
JavaScript 中的 getter 和 setter 用于定义计算属性或访问器。计算属性是使用函数获取或设置对象值的属性。基本理论是这样的:
var user = { /* ... object with getters and setters ... */ };
user.phone = '+1 (123) 456-7890'; // updates a database
console.log( user.areaCode ); // displays '123'
console.log( user.area ); // displays 'Anytown, USA'
这对于在访问属性时自动执行幕后操作非常有用,例如保持数字在范围内、重新格式化字符串、触发值已更改事件、更新关系数据、提供对私有属性的访问等等。
下面的示例显示了基本语法,尽管它们只是获取和设置内部对象值而不做任何特殊操作。在实际情况下,您将修改输入和/或输出值以满足您的需要,如上所述。
获取/设置关键字
ECMAScript 5 支持定义计算属性get
的set
关键字。它们适用于除 IE 8 及以下版本之外的所有现代浏览器。
var foo = {
bar : 123,
get bar(){ return bar; },
set bar( value ){ this.bar = value; }
};
foo.bar = 456;
var gaz = foo.bar;
自定义 Getter 和 Setter
get
并且set
不是保留字,因此可以重载它们以创建您自己的自定义跨浏览器计算属性函数。这适用于任何浏览器。
var foo = {
_bar : 123,
get : function( name ){ return this[ '_' + name ]; },
set : function( name, value ){ this[ '_' + name ] = value; }
};
foo.set( 'bar', 456 );
var gaz = foo.get( 'bar' );
或者对于更紧凑的方法,可以使用单个函数。
var foo = {
_bar : 123,
value : function( name /*, value */ ){
if( arguments.length < 2 ){ return this[ '_' + name ]; }
this[ '_' + name ] = value;
}
};
foo.value( 'bar', 456 );
var gaz = foo.value( 'bar' );
避免做这样的事情,这会导致代码膨胀。
var foo = {
_a : 123, _b : 456, _c : 789,
getA : function(){ return this._a; },
getB : ..., getC : ..., setA : ..., setB : ..., setC : ...
};
对于上面的示例,内部属性名称使用下划线进行抽象,以阻止用户简单地做foo.bar
vsfoo.get( 'bar' )
并获得“未煮熟”的值。name
您可以根据要访问的属性的名称(通过参数)使用条件代码来执行不同的操作。
Object.defineProperty()
UsingObject.defineProperty()
是另一种添加 getter 和 setter 的方法,可以在对象被定义后使用。它还可以用于设置可配置和可枚举的行为。此语法也适用于 IE 8,但不幸的是仅适用于 DOM 对象。
var foo = { _bar : 123 };
Object.defineProperty( foo, 'bar', {
get : function(){ return this._bar; },
set : function( value ){ this._bar = value; }
} );
foo.bar = 456;
var gaz = foo.bar;
__defineGetter__()
最后,__defineGetter__()
是另一种选择。它已被弃用,但仍在网络上广泛使用,因此不太可能很快消失。它适用于除 IE 10 及以下版本之外的所有浏览器。尽管其他选项在非 IE 上也能很好地工作,但这个选项并不是那么有用。
var foo = { _bar : 123; }
foo.__defineGetter__( 'bar', function(){ return this._bar; } );
foo.__defineSetter__( 'bar', function( value ){ this._bar = value; } );
另外值得注意的是,在后面的示例中,内部名称必须与访问器名称不同以避免递归(即,foo.bar
调用foo.get(bar)
调用foo.bar
调用foo.get(bar)
...)。
也可以看看
MDN get , set ,
Object.defineProperty() , __defineGetter__() , __defineSetter__()
MSDN
IE8 Getter 支持