交换()函数会产生比内联工作更干净的代码(DRY)。遗憾的是,由于JavaScript参数中的始终是按值传递的,因此以下函数什么也做不了
function swap(a,b) { var temp=a; a=b; b=temp; }
有没有办法编写一个函数来完成这个尝试,特别是对于数值呢?
我对this related question的回答不太满意。
This answer有正确的想法,但不能处理一般情况。
发布于 2013-09-16 06:39:33
我发现了这种方法,这并不是太糟糕(至少对我来说是这样):
function swap( swap_name_a, swap_name_b )
{
eval
(
"var swap_temp="+swap_name_a+";"
+ swap_name_a+"="+swap_name_b+";"
+ swap_name_b+"=swap_temp;"
);
}
您需要引用以下参数:
swap('a','b');
它似乎也适用于更复杂的参数:
swap('list[index1]','list[index2]');
注意:交换()函数需要在要使用的每个作用域中实现,因为它必须能够访问命名参数。这与“不要重复自己”原则背道而驰,但在某些情况下,复制和粘贴一些这样的样板代码可能是可以接受的,如果这会简化算法逻辑的话。
顺便说一句:The example from which I derived this从swap()返回字符串,并依赖调用者将字符串转发到eval:eval(swap('a','b'))
。这解决了作用域问题,但使交换操作更容易出错--也不太吸引人。
请注意,该消息来源还警告说,这种方法可能会导致taunting。
如果你使用eval()
,时空旅行的吸血鬼会盗取你的信用卡吗?你应该自己决定,但这里有一些帮助:
我看到的最大的担忧是,这可能相对较慢(取决于解释器管理缓存的方式)。如果它对于你的目的来说太慢了,那么就不要使用它。
发布于 2013-09-16 06:03:21
正如您正确识别的那样,由于参数是通过值传递的,因此您不能编写替换块的函数:
var a,b;
...
var tmp = a; a = b; b = tmp;
但是,如果两者都是对象的值,则可以执行此操作:
var o = {};
o.a = 3;
o.b = 4;
function swap(obj) { var tmp = obj.a; obj.a = obj.b; obj.b = tmp; }
swap(o);
您还可以泛化交换:
function swap(obj, a, b) { var tmp = obj[a]; obj[a] = obj[b]; obj[b] = tmp; }
swap(o,'a','b')
您还可以将其作为原型函数:
Object.prototype.swap = function(a,b) { var tmp = this[a]; this[a] = this[b]; this[b] = tmp; }
o.swap('a','b')
发布于 2018-01-13 09:55:57
在EMCAScript 6中,您可以滥用destructuring assignment功能。
var x = 1, y = 2;
console.log(`x = ${x}, y = ${y}`);
[x, y] = [y, x];
console.log(`x = ${x}, y = ${y}`);
MDN实际上将此作为其示例之一。
编辑:
不知何故,我遗漏了问题中的粗体字。如果你绝对需要它是一个函数,这种类型符合定义(绝对是一个笑话):
function swap() {
return [arguments[1], arguments[0]];
}
var x = 1, y = 2;
console.log(`x = ${x}, y = ${y}`);
[x, y] = swap(x, y);
console.log(`x = ${x}, y = ${y}`);
https://stackoverflow.com/questions/18817810
复制相似问题