Edw*_*uay 17 javascript oop getter-setter
来自C#/ PHP,我想在我用Javascript创建的类(函数)上有完整的getter/setter.
但是,在我遇到的大部分Javascript代码中,都没有使用getter和setter,而是使用简单的公共变量.
我很高兴找到John Resig关于getter和setter 的文章,但是有些评论说它有些浏览器"不支持getter和setter"这让我感到困惑,因为它们不是Javascript的"特性"而是更多的简单模式,使用基本的Javascript语法.这篇文章也是在2007年写的,所以它现在可能已经过时了.
Javascript中getter和setter的当前状态是什么?它们确实被所有浏览器"支持"(无论这意味着什么)?它们是Javascript的有用编程模式还是Javascript类(函数)更好地使用公共变量?有没有比以下更好的方法来实现它们?
$(document).ready(function() {
var module = new Module('idcode');
module.set_id_code('new idcode');
module.set_title('new title');
$('body').html(module.get_id_code()+': '+module.get_title());
});
function Module(id_code, title) {
var id_code = id_code;
var title = title;
//id_code
this.get_id_code = function() {
return id_code;
}
this.set_id_code = function(value) {
id_code = value;
}
//title
this.get_title = function() {
return title;
}
this.set_title = function(value) {
title = value;
}
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*own 15
Firefox,Safari,Chrome和Opera(但不是IE)都内置了相同的非标准getter和setter机制.ECMAScript 5包含一种不同的语法,目前正在进入浏览器并将成为未来的标准.IE 8已经具有此功能,但仅限于DOM节点,而不是常规的本机JavaScript对象.这是语法的样子:
var obj = {};
Object.defineProperty(obj, "value", {
get: function () {
return this.val;
},
set: function(val) {
this.val = val;
}
});
Run Code Online (Sandbox Code Playgroud)
我想你错过了这一点.(或者其他的应答者都缺少了这一点.)的ECMAScript提供了一个"背后的幕后"的getter/setter机制,使
x.foo = 3;
y = x.foo;
Run Code Online (Sandbox Code Playgroud)
真的翻译成(有点)
x.PutValue("foo",3);
y = x.GetValue("foo");
Run Code Online (Sandbox Code Playgroud)
where PutValue和GetValue是未命名的,不是属性的setter和getter的直接访问函数.(参见ECMAScript标准,第3版,第8.7.1节和第8.7.2节)第3版似乎没有明确定义用户如何设置自定义getter和setter函数.Mozilla的Javascript实现确实做到了,例如(这是在使用Javascript 1.8的JSDB中):
js>x = {counter: 0};
[object Object]
js>x.__defineGetter__("foo", function() {return this.counter++; });
js>x.foo
0
js>x.foo
1
js>x.foo
2
js>x.foo
3
js>x.foo
4
Run Code Online (Sandbox Code Playgroud)
语法是(或至少到目前为止)浏览器特定的.特别是缺少Internet Explorer,至少根据这个SO问题.
第5版ECMAScript标准似乎确实标准化了这种机制.在getter和setter上看到这个问题.
编辑:一个更实际的例子,也许,为了您的目的:
function makePrivateObject()
{
var state = 0;
var out = {};
out.__defineSetter__("foo", function(x) {});
// prevent foo from being assigned directly
out.__defineGetter__("foo", function() { return state; });
out.count = function() { return state++; }
return out;
}
js>x = makePrivateObject()
[object Object]
js>x.foo
0
js>x.foo = 33
33
js>x.foo
0
js>x.count()
0
js>x.count()
1
js>x.count()
2
js>x.foo
3
Run Code Online (Sandbox Code Playgroud)
怎么样:
function Module(id_code, title) {
var id_code = id_code;
var title = title;
var privateProps = {};
this.setProperty = function(name, value) {
// here you could e.g. log something
privateProps[name] = value;
}
this.getProperty = function(name) {
return privateProps[name];
}
}
Run Code Online (Sandbox Code Playgroud)
此处的getter和setter方法作用于私有对象,该私有对象用于存储无法从任何其他方法访问的属性.例如,只要修改了属性(getter/setter方法的目的之一),就可以实现一个setter(或getter)来记录或执行ajax或其他任何东西.
您实际上可以在javascript中定义setter和getter,而不仅仅是模仿它们.我认为它适用于除IE8及以下版本的所有浏览器.
$(document).ready(function() {
var module = new Module('idcode');
module.id = 'new idcode';
module.title = 'new title';
$('body').html(module.id + ': ' + module.title);
});
function Module(id, title) {
return {
id_code: id_code,
_title: title,
get id() {
return id_code;
},
set id(value) {
id_code = value;
},
get title() {
return _title;
},
set title(value) {
title = value;
}
}
};
Run Code Online (Sandbox Code Playgroud)
getter 和 setter 不是功能,而是不支持属性语法的语言的“设计模式”(在本例中为代码膨胀)。
由于 Javascript 不需要 getter 和 setter,因此您不想编写它们。使用您可以使用的语言功能,并且在一种语言中效果很好的习语在另一种语言中效果不佳。
我最喜欢的引言之一来自 Python 社区:
我们都是同意的成年人
在讨论为什么不需要私有变量和信息隐藏时。
可以在此处找到报价。
了解该语言为您提供的内容并接受其文化和规则。