用Javascript创建类getter/setter的最佳方法?
来自C#/PHP,我希望对使用Javascript创建的类(函数)拥有完整的getter/setter 然而,在我遇到的许多Javascript代码中,没有使用getter和setter,而是使用简单的公共变量 我很高兴看到关于getter和setter的文章,但是一些评论指出一些浏览器“不支持getter和setter”,这让我很困惑,因为它们不是Javascript的“特性”,而是一个使用基本Javascript语法的简单模式。这篇文章也是在2007年写的,所以现在可能已经过时了 Javascript中getter和setter的当前状态是什么?它们是否真的得到了当今所有浏览器的“支持”(无论这意味着什么)?它们是Javascript的有用编程模式还是Javascript类(作为函数)使用公共变量更好?有没有比下面更好的方法来实现它们用Javascript创建类getter/setter的最佳方法?,javascript,oop,getter-setter,Javascript,Oop,Getter Setter,来自C#/PHP,我希望对使用Javascript创建的类(函数)拥有完整的getter/setter 然而,在我遇到的许多Javascript代码中,没有使用getter和setter,而是使用简单的公共变量 我很高兴看到关于getter和setter的文章,但是一些评论指出一些浏览器“不支持getter和setter”,这让我很困惑,因为它们不是Javascript的“特性”,而是一个使用基本Javascript语法的简单模式。这篇文章也是在2007年写的,所以现在可能已经过时了 Javas
$(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;
}
}
getter和setter不是特性,而是不支持属性语法的语言的“设计模式”(本例中的代码膨胀) 因为Javascript不需要getter和setter,所以您不想编写它们。使用您可以使用的语言功能,在一种语言中效果很好的习惯用法在另一种语言中效果不太好 我最喜欢的一句话来自Python社区: 我们都是成年人 当讨论为什么不需要私有变量和信息隐藏时 报价可以找到 了解该语言为您提供了什么,并接受其文化和规则。如何:
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];
}
}
这里的getter和setter方法作用于私有对象,该私有对象用于存储无法从任何其他方法访问的属性。例如,您可以实现一个setter(或getter),它记录或执行ajax或其他任何操作,只要属性被修改(getter/setter方法的目的之一)。我认为您没有抓住要点。(或者其他回答者可能没有抓住要点。)ECMAScript提供了一种“幕后”getter/setter机制,以便
x.foo = 3;
y = x.foo;
真的翻译成(某种程度上)
其中,PutValue
和GetValue
是未命名的,不能直接访问setter函数和属性getter函数。(参见,第8.7.1.和8.7.2节)第三版似乎没有明确定义用户如何设置自定义getter和setter函数。Mozilla的Javascript实现过去和现在都是如此,例如(这是使用Javascript 1.8的版本):
语法是(或至少到目前为止是)特定于浏览器的。至少根据调查,Internet Explorer尤其缺乏
ECMAScript标准的第5版似乎确实在这一机制上实现了标准化。看
编辑:也许出于您的目的,有一个更实际的例子:
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
Firefox、Safari、Chrome和Opera(但不是IE)都有相同的非标准内置机制。ECMAScript 5包含一种不同的语法,现在是,将来也将成为标准。IE8已经有了这个特性,但只在DOM节点上,而不是在常规的本机JavaScript对象上。这就是语法的样子:
var obj = {};
Object.defineProperty(obj, "value", {
get: function () {
return this.val;
},
set: function(val) {
this.val = val;
}
});
实际上,您可以在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;
}
}
};
我喜欢这样:
// Module
var Module = function() {
// prive getter/setter value
var __value;
// private getter/setter method
var _value = function() {
if(!arguments.length) return __value;
else __value = arguments[0];
};
// output/public
return {
value: _value
};
}
我喜欢的一种可靠的语义方式是使用和。例如,我创建了以下对象:
var myComplexObject={
更改日志:{},
日志:函数(名称,val){
console.log(“将“+name+”设置为“+val”);
如果(!this.changelog[名称])
this.changelog[name]=[];
this.changelog[name].push(val);
},
设置o(val){
这个.log(“o”,val);
},
得到o(){
log(“你永远不会知道真正的值!”);
返回42;
}
}
在这里,无论何时读取或修改o
的值,行为都是定制的。以以下代码行及其控制台输出为例:
myComplexObject.o=“氧气”;
将氧设置为氧气
然后,在本例中,尝试读取值会导致以下结果:
var read=myComplexObject.o;
console.log(读取);
你永远不会知道真正的价值!
42
在此示例中,将记录您设置的每个新值:
myComplexObject.o=“哦,不!”;
log(myComplexObject.changelog.o);
将o设置为哦不!
[“氧气”,“哦,不!”]
确切地说,我不希望代码膨胀,但我希望像在PHP和C#等其他语言中一样,将对类的公共访问和私有访问分开。PHP有uuu get和uu set魔术方法,而C有其“属性语法”,可以在不使用臃肿语法的情况下实现分离。Javascript中有这样的功能吗?上面的代码是否在IE 7/8/9中工作,但没有提供任何有用的功能。setProperty和getProperty是公共函数,因此这只是增加了一个间接级别。它没有添加调用私有getter和setter函数的功能。它添加了除了通过getter和setter方法之外无法访问的属性,就像公共getter和setter方法用于修改其他语言中的私有成员一样。这是一个演示——这些方法也可以做其他事情。这很公平——但要么在代码中添加一个钩子来实现,要么在代码中添加一个注释来修改行为。是的,这对资深javascript程序员来说是显而易见的,但对初学者来说并非如此。@Jason s-补充了一些解释。这可能是内部处理它们的方式,但从技术上讲,如果我无法控制对它们的访问,它们仍然是“公共变量”。getter和setter对我来说的优点是,我可以确定,例如,“Salary”属性只能在内部更改,或者,当它被更改时,(a)更改被记录,(b)事件被触发,等等,除非我有getter/setter访问
$(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;
}
}
};
// Module
var Module = function() {
// prive getter/setter value
var __value;
// private getter/setter method
var _value = function() {
if(!arguments.length) return __value;
else __value = arguments[0];
};
// output/public
return {
value: _value
};
}