我一直在尝试解决 getter 和 setter 问题,但并没有深入了解。我已经阅读了JavaScript Getter 和 Setter以及Defining Getter 和 Setter,但没有得到它。
有人可以明确说明:
- getter 和 setter 的作用是什么,以及
- 举一些非常简单的例子?
我一直在尝试解决 getter 和 setter 问题,但并没有深入了解。我已经阅读了JavaScript Getter 和 Setter以及Defining Getter 和 Setter,但没有得到它。
有人可以明确说明:
除了@millimoose 的回答之外,setter 也可用于更新其他值。
function Name(first, last) {
this.first = first;
this.last = last;
}
Name.prototype = {
get fullName() {
return this.first + " " + this.last;
},
set fullName(name) {
var names = name.split(" ");
this.first = names[0];
this.last = names[1];
}
};
现在,您可以设置fullName
,并first
与last
将被更新,反之亦然,副。
n = new Name('Claude', 'Monet')
n.first # "Claude"
n.last # "Monet"
n.fullName # "Claude Monet"
n.fullName = "Gustav Klimt"
n.first # "Gustav"
n.last # "Klimt"
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'
这对于在访问属性时自动执行幕后操作非常有用,例如将数字保持在范围内、重新格式化字符串、触发 value-has-changed 事件、更新关系数据、提供对私有属性的访问等等。
下面的示例显示了基本语法,尽管它们只是简单地获取和设置内部对象值,而没有做任何特殊的事情。在实际情况下,您可以修改输入和/或输出值以满足您的需要,如上所述。
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;
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
vs.foo.get( 'bar' )
并获得“未煮过的”值。您可以根据正在访问的属性的名称(通过name
参数)使用条件代码执行不同的操作。
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__()
是另一种选择。它已被弃用,但仍在网络上广泛使用,因此不太可能很快消失。它适用于除 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 支持
例如,您可以使用它们来实现计算属性。
例如:
function Circle(radius) {
this.radius = radius;
}
Object.defineProperty(Circle.prototype, 'circumference', {
get: function() { return 2*Math.PI*this.radius; }
});
Object.defineProperty(Circle.prototype, 'area', {
get: function() { return Math.PI*this.radius*this.radius; }
});
c = new Circle(10);
console.log(c.area); // Should output 314.159
console.log(c.circumference); // Should output 62.832
很抱歉重新提出一个老问题,但我想我可能会贡献一些非常基本的例子和傻瓜解释。迄今为止发布的其他答案都没有像MDN 指南的第一个示例那样说明语法,这与人们所能获得的基本一样。
吸气剂:
var settings = {
firstname: 'John',
lastname: 'Smith',
get fullname() { return this.firstname + ' ' + this.lastname; }
};
console.log(settings.fullname);
...John Smith
当然会记录。一吸气表现得像可变对象的属性,但提供的功能,实时计算其返回值的灵活性。它基本上是一种创建调用时不需要 () 的函数的奇特方式。
二传手:
var address = {
set raw(what) {
var loc = what.split(/\s*;\s*/),
area = loc[1].split(/,?\s+(\w{2})\s+(?=\d{5})/);
this.street = loc[0];
this.city = area[0];
this.state = area[1];
this.zip = area[2];
}
};
address.raw = '123 Lexington Ave; New York NY 10001';
console.log(address.city);
...将登录New York
到控制台。与 getter 一样,setter的调用语法与设置对象属性的值相同,但它是另一种不使用 () 调用函数的奇特方式。
请参阅此 jsfiddle以获得更全面、更实用的示例。将值传递到对象的setter会触发其他对象项的创建或填充。具体来说,在jsfiddle的例子中,传递一个数字数组会提示setter计算均值、中位数、众数和范围;然后为每个结果设置对象属性。
只有当您拥有类的私有属性时,getter 和 setter 才真正有意义。由于 Javascript 并不像您通常从面向对象语言中想到的那样真正具有私有类属性,因此可能难以理解。这是私有计数器对象的一个示例。这个对象的好处是不能从对象外部访问内部变量“count”。
var counter = function() {
var count = 0;
this.inc = function() {
count++;
};
this.getCount = function() {
return count;
};
};
var i = new Counter();
i.inc();
i.inc();
// writes "2" to the document
document.write( i.getCount());
如果您仍然感到困惑,请查看 Crockford 关于Private Members in Javascript的文章。