swap()函数会产生比内联工作更清晰的代码(DRY)。不幸的是,以下函数没有任何结果,因为JavaScript参数中的始终是按值传递:
function swap(a,b) { var temp=a; a=b; b=temp; }
有没有办法编写一个函数来完成正在尝试的内容,特别是对于数值?
我对this related question的答案印象不深 This answer有正确的想法,但不处理一般情况。
答案 0 :(得分:2)
正确识别后,由于参数是按值传递的,因此无法编写替换块的函数:
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')
答案 1 :(得分:1)
使用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}`);
答案 2 :(得分:-2)
要使swap(a,b)像在C中一样工作,您需要引用变量。它可以比上面的答案1更轻。只是
function swap(n, m) {
var temp = this[n];
this[n] = this[m];
this[m] = temp;
}
此功能中的此是窗口,并且呼叫是 swap('a','b')。当然,您可以使用逻辑或算术避免局部变量 temp (对于 int )。
答案 3 :(得分:-3)
我找到了这种方法,这不是太糟糕(至少对我而言):
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]');
注意:您需要在将要使用的每个范围内实现swap()函数,因为它必须能够访问命名参数。这违背了“不重复自己”的原则,但在某些情况下,如果能够简化算法逻辑,那么复制并粘贴一些像这样的样板代码是可以接受的。
顺便说一句:The example from which I derived this从swap()返回字符串,并依赖调用者将字符串转发给eval:eval(swap('a','b'))
。这解决了范围问题,但使交换操作更容易出错 - 而且吸引力更小。
请注意,该来源还警告此方法可能会导致taunting。
如果您使用eval()
,时间旅行的太空吸血鬼会偷走您的信用卡吗?你应该自己决定,但这里有一些帮助:
我看到的最大问题是这个可能相对较慢(取决于解释器如何管理缓存)。如果它对你的目的太慢,那就不要使用它。