Modify a variable inside a function
假设我有一个内联脚本标记,它有一个非常简单的代码,如下所示
1 2 3 4 5 6 7 8 9 10 11
| (function() {
var test ="This is a simple test";
function modifyTest(s) {
s ="Modified test text";
};
modifyTest(test);
console.log(test) //Will still display"This is a simple test"
})(); |
但是如果我使用test = modifyTest(test);。改变是适用的,我的问题是。这是在函数内部修改javascript变量的唯一方法吗,这意味着我必须始终这样做
source = function(source);为了改变函数中的变量,
或者我是否错过了一个阻止我完成这项工作的范围概念?
- javascript使用传递值,而不是传递引用。给变量赋值永远不会改变另一个变量的值。如果要更改特定变量的值,则必须显式分配给该变量。
- @FelixKling:"使用传递值,而不是通过引用传递"——这并不完全正确。它按值传递引用(对于引用类型)
- @泽克斯:我很确定。如果您记住了对象,那么这些值就是对对象的引用。传递引用是一个定义很好的术语。
- @felix kling:var a = {}; console.log(a);<--这里传递了对a的引用
- 泽尔克姆斯:不。en.wikipedia.org/wiki/评估策略
- @费利克斯·克林:它与函数调用无关,特别是var a = {}; var b = a;。
- javascript同时执行传递值和传递引用。这取决于你如何使用它。
- @zerkms:不是。通过引用传递或赋值意味着变量得到对另一个变量的引用,而不是对其值的引用。javascript总是传递值,对于对象,该值是对对象的引用,而不是对变量的引用。你所指的是维基百科文章中的分享呼叫:en.wikipedia.org/wiki/evaluation-strategy-call-by-sharing,但本质上它是按价值传递的。
- Felix是正确的;如果您将3个vars设置为同一个对象,并且将其中一个设置为空,那么其他两个仍然是同一个对象。
- duh,都在同一点上-"它通过值传递引用""本质上它是传递值"
- @loxy:ha,我还是没看到那个部分:d,它是传递值,不是传递引用,因为这意味着一些不同的东西。
- @菲利克斯·克林:是的,现在我看到了最初的观点,道歉:—)
- @丹达维如果改变了对象属性的值会怎么样?var a=x:1,y:2 var b=a;var c=a;b.x=10;console.log(c.x);
- @泽克斯:不用担心:)在这个层面上,我想很容易误解对方;)我也误解了你……很抱歉!
- @Anmolsaraf:你正在改变对象本身,你不会改变变量的值。
- javascript总是按值传递变量。这与Java中的相同:"按引用调用"。由于对象类型的值是内存地址(有些是引用),所以看起来对象是通过引用传递的。
- 我的评论说他们是同一个对象…对于操作中的字符串,这很简单…
- 我试着用javascript创建malloc/free实现,注意到那些不修改传入值的函数,所以我决定问一下guru非常有洞察力的东西,javascript使用得越多就越有趣。我想我会用伊桑的例子,把我的"记忆"包装在对象中,这样它们就可以"通过引用传递"来完成我想要做的事情。
- 在javascript btw中不需要free。如果某个变量不在任何具有指向它的有效引用的函数的范围内,它应该由引擎自动释放。
- 我知道gc会自动"释放"不再指向任何东西的变量,所以本质上,这是所有的自由都会告诉gc你已经完成了它(通过设置它为空,这样它就不再持有一个引用),这只是一个受lljs启发的玩具项目。
modifyTest函数本质上是创建一个称为s的局部函数级变量;该变量只存在于函数的作用域内,因此修改它不会影响外部作用域。
如果要修改外部作用域,则不使用参数:
1 2 3 4 5 6 7
| var test ="This is a simple test";
function modifyTest(){
test ="modified test text";
}
console.log(test); // This is a simple test
modifyTest();
console.log(test); // Modified test text |
不能修改通过引用传递的对象,因此可以修改某个对象的属性:
1 2 3 4 5 6
| var o = { test: 'This is a simple test' };
function modifyTest(x){
x.test = 'modified test text';
}
modifyTest(o);
console.log(o.test); // modified test text |
您甚至可以以您希望修改的属性的名称传递:
1 2 3 4 5 6
| var o = { test: 'This is a simple test' };
function modifyTest(x, name){
x[name] = 'modified test text';
}
modifyTest(o, 'test');
console.log(o.test); // modified test text |
- 我的问题是我需要传入变量,因为实际上想要修改一个"静态"变量是没有意义的,它应该是动态的。
- 我不认为你在正确的上下文中使用了"静态"和"动态"两个词。您的意思是您希望能够按名称修改任何变量。如果这是你的目标,你应该看看我的第二个例子,使用一个对象并修改它的一个参数。没有办法按你的要求去做,这是你应该做的。
- 然而,这个对象示例很有趣,也许我可以更改代码来使用一个对象,这样我就可以完成这个任务。
- 您可以通过sweet js(sweetjs.org)等工具查看javascript中的宏,但我可能会先考虑一下您的问题。
- 欺骗变量可见性/范围的另一种方法是返回引用了局部变量的函数。这是在JavaScript中获取私有变量的常用方法。
- 我的意思是,用户应该能够创建传入的变量,而不仅仅是一个存在的全局变量。在代码中的某一点上(如果有意义的话)
- 它是有意义的(我知道你的意思),但是"动态"和"静态"在计算机语言方面有非常具体的含义。我是个爱说话的人;)
您所说的是"通过引用"调用函数。JavaScript(与大多数其他函数语言一样)不支持这种情况,因为更改当前范围之外的变量是一种副作用,而这些副作用与函数编程范式相矛盾。
但是,您始终可以更改当前范围内的变量。因此,在另一个函数中定义的任何函数都可以更改外部函数的任何局部变量。