2011-04-28 102 views
5

您能否提出任何解决方法来实现使用闭包或其他技巧引用变量?javascript如何创建参考

createReference = function() { 
    // TODO: how to implement? 
}; 

var x = 5; 
var refX = createReference(x); // could be any parameters needed to implement the logic 
x = 6; 
alert(refX()); // should alert 6 

什么有关传递上下文第一个参数,并传递变量名称(如串)和后以某种方式评估预定义的上下文参考。这是可行的吗?

这里有一个更完整的场景:

createReference = function(context, prop) { 
    return function() { 
     return context[prop]; 
    }; 
}; 

Provider = function() { 
}; 
Provider.prototype.x = 5; 
Provider.prototype.getXRef = function() { 
    return createReference(this, 'x'); 
}; 
Provider.prototype.incrementX = function() { 
    this.x = this.x + 1; 
}; 

var provider = new Provider(); 
var refX = provider.getXRef(); 
provider.incrementX(); 
alert(refX()); 
+1

将来,请不要将您的问题作为代码中的嵌入式注释提出。这使得很难看到这个问题,而且让人们认为这不是一个问题。 – Oded 2011-04-28 19:28:42

+0

我很高兴我回答了你的问题,但是,在你更新的场景中,为什么不直接使用:'Provider.prototype.getXRef = function(){var that = this;返回函数(){return that.x; }; };'这样你可以避免使用字符串? – brianpeiris 2011-04-28 20:23:08

+0

createReference是通用的方法。那么在不同的情况下,我只会使用这种通用的方式。关于你的评论:它冷没有Provider.prototype.getXRef方法,但在其他一些方法可能我想传递引用一些其他对象作为回调参数等...它会更可读写createReference(这, 'x')then function(){var that = this;返回函数(){return that.x; }; };在日常使用中。 – 2011-04-28 20:37:36

回答

5

你必须使用变量名的字符串,但我认为这是接近你永远可以在javascript:

var createReference = function (context, prop) { 
    return function() { return context[prop]; }; 
}; 

var x = 5; 
var refX = createReference(this, 'x'); 
x = 6; 

alert(refX()); // alerts 6 

编辑:

在你更新的情况下,最好直接使用闭包,以便不必使用变量名称的字符串:

var createReference = function (context, func) { 
    return function() { return func.call(context); } 
}; 

Provider = function() { 
}; 
Provider.prototype.x = 5; 
Provider.prototype.getXRef = function() { 

    return createReference(this, function() { return this.x; }); 

    // OR if you happen to be running in a 
    // JavaScript 1.8 environment like Firefox 3+, 
    // you can use "expression closures" for more 
    // concise code: 

    // return createReference(this, function() this.x); 
}; 
Provider.prototype.incrementX = function() { 
    this.x = this.x + 1; 
}; 

var provider = new Provider(); 
var refX = provider.getXRef(); 
provider.incrementX(); 
alert(refX()); // alerts 6 
+0

是的,不错的选择。但是,javascript不是以save方式保存的,并且名称误用时不会出现“编译时”错误,因此我认为最好使用更短且更易读的方法(对于我)代码,而不使用字符串方式。 – 2011-04-28 21:42:45

0

你不能只是促进x做个参考。

+0

使用闭包等的任何解决方法? – 2011-04-28 19:29:49

2

在JavaScript中,您不能通过引用传递基元值(数字,字符串等)。但是,您传递的每个对象都将始终作为参考。 (这包括阵列)

要使用例如:

var foo = { x: 5 }; 
var refFoo = foo; 

// foo.x => 5 
// refFoo.x => 5 

foo.x = 6; 

// foo.x => 6 
// refFoo.x => 6 
+0

有没有办法用'new Number(4)'做到这一点?这是一个对象。你可以(重新)将它的价值设定为“保持活力”并让它通过?像'n =新数字(4); N2 = N; n2.setValue(7); alert(n);' – Rudie 2011-04-28 19:36:39

+0

是的,那将是一个对象。在技​​术上,几乎所有的JS都是一个对象。但是,标量值(数字,字符串等)不会被引用传递,这只是JS的工作方式。 – 2011-04-28 20:04:16

+0

我知道这是一个对象,但是如何更改Number对象的值? '.setValue'不存在,你不能重新分配一个新的对象,因为你失去了对'n'的引用。不要工作:'n2 = 7;','n2 = new Number(7);','n2.setValue(7);'。前两个失去参考,第三个不存在。 **如何更改数字对象的值?** – Rudie 2011-04-29 08:02:52

0

只有非标量类型可如引用传递,并且将始终作为引用传递:

var reference = {}; 
my_function(reference); 
console.log(reference); // will show property - a property value 

function my_function(my_reference) { 
    my_reference.property = "a property value"; 
} 

var not_a_reference = []; 
my_function(not_a_reference); 
console.log(not_a_reference); // will NOT show 'a value' 

function my_function() { 
    my_reference.push("a value"); 
} 

接近你例如:

function show(value) { 
    alert(value.data); 
} 

var value = { 'data': 5 }; 
show(value); // alerts 5 
value.data = 6; 
show(value); // alerts 6 
0

由于对象始终是静态引用,因此您可以这样做:

var o = {}; 
o.x = 5; 
var oRef = o; 
alert(oRef.x); // -> 5 
o.x = 6; 
alert(oRef.x); // -> 6