Javascript 假人的getter\setter
我一直在试着让我的头脑围绕着接球手和二传手,但我并没有陷入其中。我读过,只是不明白 有人能清楚地说明:Javascript 假人的getter\setter,javascript,setter,getter,Javascript,Setter,Getter,我一直在试着让我的头脑围绕着接球手和二传手,但我并没有陷入其中。我读过,只是不明白 有人能清楚地说明: 一个能手和二传手应该做什么,以及 举一些非常简单的例子 我认为你链接到的第一篇文章非常清楚地说明了这一点: 以这种方式编写JavaScript的明显优势在于,您可以使用它来隐藏您不希望用户直接访问的值 这里的目标是通过只允许通过get()或set()方法访问字段来封装和抽象字段。通过这种方式,您可以以任何方式在内部存储字段/数据,但外部组件仅位于发布的接口之外。这允许您在不更改外部接口的情况下
我认为你链接到的第一篇文章非常清楚地说明了这一点: 以这种方式编写JavaScript的明显优势在于,您可以使用它来隐藏您不希望用户直接访问的值
这里的目标是通过只允许通过
get()
或set()
方法访问字段来封装和抽象字段。通过这种方式,您可以以任何方式在内部存储字段/数据,但外部组件仅位于发布的接口之外。这允许您在不更改外部接口的情况下进行内部更改,在set()
方法中执行一些验证或错误检查等。例如,您可以使用它们来实现计算属性
例如:
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
如果您指的是访问器的概念,那么简单的目标就是隐藏底层存储,使其免受任意操作。最极端的机制是
function Foo(someValue) {
this.getValue = function() { return someValue; }
return this;
}
var myFoo = new Foo(5);
/* We can read someValue through getValue(), but there is no mechanism
* to modify it -- hurrah, we have achieved encapsulation!
*/
myFoo.getValue();
如果您指的是实际的JS getter/setter特性,例如
defineGetter
/defineGetter
,或{get Foo(){/*code*/}}
,那么值得注意的是,在大多数现代引擎中,这些属性的后续使用将比其他情况慢得多。比较两种方法的性能
var a = { getValue: function(){ return 5; }; }
for (var i = 0; i < 100000; i++)
a.getValue();
var a={getValue:function(){return 5;};}
对于(变量i=0;i<100000;i++)
a、 getValue();
vs
var a={get value(){return 5;};}
对于(变量i=0;i<100000;i++)
a、 价值观;
只有当您拥有类的私有属性时,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关于的文章。此外,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"
我有一个给你们的,可能有点难看,但它确实可以跨平台完成
function myFunc () {
var _myAttribute = "default";
this.myAttribute = function() {
if (arguments.length > 0) _myAttribute = arguments[0];
return _myAttribute;
}
}
这样,当你打电话的时候
var test = new myFunc();
test.myAttribute(); //-> "default"
test.myAttribute("ok"); //-> "ok"
test.myAttribute(); //-> "ok"
如果你真的想增加情趣。。您可以插入一种支票类型:
if (arguments.length > 0 && typeof arguments[0] == "boolean") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "number") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "string") _myAttribute = arguments[0];
或者更疯狂地使用高级支票:有什么让人困惑的呢。。。getter是在获取属性setter时调用的函数,设置属性setter时调用。 例如,如果你这样做了
obj.prop = "abc";
在设置属性prop时,如果使用getter/setter,则将调用setter函数,并将“abc”作为参数。
对象内的setter函数定义理想情况下如下所示:
set prop(var) {
// do stuff with var...
}
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'
我不确定跨浏览器实现的效果如何。Firefox似乎还有另一种语法,带有双下划线的特殊(“魔术”)方法。像往常一样,Internet Explorer不支持这一切。您可以通过构造函数的原型为js类定义实例方法。
以下是示例代码:
// BaseClass
var BaseClass = function(name) {
// instance property
this.name = name;
};
// instance method
BaseClass.prototype.getName = function() {
return this.name;
};
BaseClass.prototype.setName = function(name) {
return this.name = name;
};
// test - start
function test() {
var b1 = new BaseClass("b1");
var b2 = new BaseClass("b2");
console.log(b1.getName());
console.log(b2.getName());
b1.setName("b1_new");
console.log(b1.getName());
console.log(b2.getName());
}
test();
// test - end
而且,这应该适用于任何浏览器,您也可以简单地使用nodejs来运行此代码。我也有点困惑,因为我试图将一个属性添加到我没有编写的现有原型中,因此替换原型似乎是错误的方法。因此,为了子孙后代,以下是我如何将
last
属性添加到Array
:
Object.defineProperty(Array.prototype, "last", {
get: function() { return this[this.length - 1] }
});
比添加函数IMHO稍微好一点。很抱歉重新提出一个老问题,但我想我可能会提供一些非常基本的示例和傻瓜式的解释。thusfar发布的其他答案中没有一个能像第一个例子那样说明语法,这是一个最基本的例子 Getter:
var settings = {
firstname: 'John',
lastname: 'Smith',
get fullname() { return this.firstname + ' ' + this.lastname; }
};
console.log(settings.fullname);
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);
。。。当然,我们将记录约翰·史密斯的日志。getter的行为类似于变量对象属性,但提供了函数的灵活性,可以动态计算其返回值。这基本上是一种创建调用时不需要()的函数的奇特方法
设置器:
var settings = {
firstname: 'John',
lastname: 'Smith',
get fullname() { return this.firstname + ' ' + this.lastname; }
};
console.log(settings.fullname);
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);
。。。将newyork
记录到控制台。与getter一样,setter的调用语法与设置对象属性的值相同,但这是另一种不用()调用函数的奇特方法
请参阅以获得更全面、或许更实用的示例。将值传递到对象的setter会触发其他对象项的创建或填充。具体地说,在jsfiddle示例中,传递一个数字数组会提示setter计算平均值、中值、模式和范围;然后为每个结果设置对象属性。JavaScript中的getter和setter
概述
JavaScript中的getter和setter用于定义计算属性或访问器。计算属性是使用函数获取或设置对象值的属性。基本理论是这样做的:
set prop(var) {
// do stuff with var...
}
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
关键字。他们工作
var foo = {
_a : 123, _b : 456, _c : 789,
getA : function(){ return this._a; },
getB : ..., getC : ..., setA : ..., setB : ..., setC : ...
};
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;
var foo = { _bar : 123; }
foo.__defineGetter__( 'bar', function(){ return this._bar; } );
foo.__defineSetter__( 'bar', function( value ){ this._bar = value; } );
var employee = {
first: "Boris",
last: "Sergeev",
get fullName() {
return this.first + " " + this.last;
},
set fullName(value) {
var parts = value.toString().split(" ");
this.first = parts[0] || "";
this.last = parts[1] || "";
},
email: "boris.sergeev@example.com"
};
console.log(employee.fullName); //Boris Sergeev
employee.fullName = "Alex Makarenko";
console.log(employee.first);//Alex
console.log(employee.last);//Makarenko
console.log(employee.fullName);//Alex Makarenko