这可能还是我在这里咆哮错误的树?
var data = 'one';
function fnc(){
this.out = function(){
return data;
}
}
var instance = new fnc();
alert(instance.out);
data = 'two';
alert(instance.out);
// I know that this would achieve that, but that's not what I would like to know.
alert(instance.out());
data = 'two';
alert(instance.out());
更新
fnc应该代表的对象实际上是一个Sarissa dom文档。这是fnc(),dom_doc()的更精细版本。以下接受的答案已集成到下面的功能中。
function get_doc(dom_node) {
var doc;
if (navigator.userAgent.indexOf("MSIE") >= 0) {
doc = new ActiveXObject("Msxml2.DOMDocument.3.0");
doc.loadXML(document.getElementById(dom_node).text);
}
else {
doc = Sarissa.getDomDocument();
doc = (new DOMParser()).parseFromString(document.getElementById(dom_node).textContent, "text/xml");
// runs XSLTProcessor in modern browsers as if it was trasformNode
doc.transformNode = function (stylesheet) {
var processor = new XSLTProcessor();
processor.importStylesheet(stylesheet);
return new XMLSerializer().serializeToString(processor.transformToDocument(this));
}
// allows modern browsers to extract xml the way the legacy IEs did
var getXML = {};
getXML.toString = function(){
return new XMLSerializer().serializeToString(doc);
};
doc.xml = getXML;
}
return doc;
}
演示: JSFIDDLE
答案 0 :(得分:9)
您似乎在谈论 getter 方法。如果这就是你的意思,你可以使用它:
var data = 'one';
function fnc(){
Object.defineProperty(this, 'out', {
get : function(){ return data; }
});
}
var instance = new fnc();
alert(instance.out);
这与旧浏览器不兼容(请参阅this page底部的兼容性表)。
另外,使用getter获取全局变量有点奇怪。通常使用它来获取实例对象上的私有变量的值,在这种情况下,您只能使用相应的setter修改它。
答案 1 :(得分:4)
bfavaretto's解决方案的替代方法是使用对象的文字语法。与Object.defineProperty()
具有几乎相同的支持度。
此外,您应该只调用Object.defineProperty
一次,而不是每次实例化。
我还将提供一个更现实的例子,即计算属性,而不仅仅是引用全局。
http://jsfiddle.net/mendesjuan/zztYd/3/
function Pair(a,b){
this.a = a;
this.b = b;
}
Pair.prototype = {
get sum(){
return this.a + this.b;
}
};
var pair = new Pair(1,2);
alert(pair.sum);
pair.a = 5;
alert(pair.sum);
这样做的好处是你可以将实现改为存储而不是计算,你不必改变它的调用方式。
function Pair(a,b){
this.a = a;
this.b = b;
this.sum = a + b;
}
Pair.prototype = {
setA: function(a){
this.a = a;
this.sum = this.a + this.b;
}
};
var pair = new Pair(1,2);
alert(pair.sum);
pair.setA(5);
alert(pair.sum);
请注意,您现在必须调用setA
以便可以重新计算总和。或者你可以使用setter。
function Pair(a,b){
this.a = a;
this.b = b;
this.sum = a + b;
}
Pair.prototype = {
set a(a) {
this.a = a;
this.sum = this.a + this.b;
}
};
var pair = new Pair(1,2);
alert(pair.sum);
pair.a = 5;
alert(pair.sum);
答案 2 :(得分:3)
<强> jsFiddle Demo
强>
这些类型的变通办法确实绕过了惯例。简单地在你的函数上使用()
不应该是一个很大的障碍。使用()
是预期的,可读的,最佳实践和行业标准。
不确定为什么smartcaveman
决定删除他使用toString
的答案,但这是一种可行的方法,尽管有些讨厌。
var data = 'one';
function fnc(){
var getData = {};
getData.toString = function(){
return data;
};
this.out = getData;
}
var instance = new fnc();
alert(instance.out);//one
data = 'two';
alert(instance.out);//two
var s = instance.out;
alert(s);//two