Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有可能让JavasScript函数像字符串一样工作,否()_Javascript_String_Function - Fatal编程技术网

Javascript 有没有可能让JavasScript函数像字符串一样工作,否()

Javascript 有没有可能让JavasScript函数像字符串一样工作,否(),javascript,string,function,Javascript,String,Function,这是可能的还是我找错了树 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 w

这是可能的还是我找错了树

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;
}

演示:

您似乎在谈论一种getter方法。如果这就是你的意思,你可以用这个:

var data = 'one';
function fnc(){
    Object.defineProperty(this, 'out', {
        get : function(){ return data; }
    });
}
var instance = new fnc();

alert(instance.out);

这与较旧的浏览器不兼容(请参阅本部分底部的兼容性表)

另外,使用getter获取全局变量有点奇怪。通常,您可以使用它来获取实例对象上私有变量的值,在这种情况下,您只能使用相应的setter来修改它。

解决方案的另一种选择是使用对象的文本语法。与
对象的支持级别几乎相同。defineProperty()

此外,您应该只调用一次
Object.defineProperty
,而不是每次实例化

我还将提供一个更现实的示例,即计算属性,而不仅仅是引用全局

这样做的好处是,您可以将实现更改为存储而不是计算,并且不必更改它的调用方式

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);

不过,这些类型的变通方法实际上绕过了惯例。在函数上简单地使用
()
,不应该有太大的阻碍。使用
()
是预期的、可读的、最佳实践和行业标准

不知道为什么他决定删除使用
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

是的,这是可能的。这叫做getter。不是最好的dupe,但我发现@Serhiy通常,作为重复项关闭的问题会作为路标保留,供通过Google找到的人使用。@Serhiy现在我看到了你的实际代码,为什么不干脆
doc.xml=new XMLSerializer().serializeToString(doc)?@bfavareto通过setAttribute等操作xml。这是我第一次尝试的,注意到更改没有反映出来,只返回了原始的xml字符串。您不想在构造函数中调用
defineProperty
吗?为什么不像OP那样将属性定义放在构造函数中呢?@Serhiy还有文本语法
fnc.prototype={get x()function(){return data}
@bfavaretto说它在ECMAScript 5中,由IE9+/Firefox1.8.1+/Chrome/Opera9.5+/Safari3+@bfavaretto支持。看看第65页,当他的解决方案不起作用时,我希望这不是我的错。然而,这正是我所需要的,并将答案更改为这一个,因为其他两种方法在实际情况下不太有效。smartcaveman的答案只有在您使用的是自动为您调用
toString()
时才有效,如
警报
。这不是OP要问的问题,我不同意标准使用的是一种方法。JavaScript总是有属性getter/setter,只是我们(JS开发人员)无法创建自己的属性getter/setter。最简单的例子是像
document.cookie=“…”
这样的setter,它不只是设置一个属性,它在hood.OP下面调用一个方法,这里是上下文,在这里这是唯一有效的答案,至于为什么我接受这个答案而不是其他答案,以防有人感兴趣@胡安曼德斯-我相信你在做这些陈述时是在歪曲“精神”。请阅读这篇关于meta的文章:在你开始全面了解stackoverflow是什么或不是什么,或者开始口述OP应该或不应该接受什么之前,先在meta上发表一篇关于“SO精神”的文章。注意下面的部分:“底线是你应该接受你认为对你个人最有帮助的答案。”+1是一个实际有用的getter示例,对于ecma规范上带有页码的注释:)只有一件事:这个语法显然更简单,但是Object.defineProperty并不一定要在每次实例化时调用;它可以在构造函数的原型上使用,就像您在这里所做的那样。@bFavareto修复了文本,因此它并不意味着
Object.defineProperty
不一定要在每次实例化时调用
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