与内联工作相比,swap() 函数会产生更简洁的代码 ( DRY )。不幸的是,以下函数什么也没做,因为在 JavaScript 中参数总是按值传递:
function swap(a,b) { var temp=a; a=b; b=temp; }
有没有办法编写一个函数来完成这个尝试,特别是对于数值?
与内联工作相比,swap() 函数会产生更简洁的代码 ( DRY )。不幸的是,以下函数什么也没做,因为在 JavaScript 中参数总是按值传递:
function swap(a,b) { var temp=a; a=b; b=temp; }
有没有办法编写一个函数来完成这个尝试,特别是对于数值?
正如您正确识别的那样,由于参数是按值传递的,因此您不能编写替换块的函数:
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')
使用 EMCAScript 6,您可以滥用解构赋值功能。
var x = 1, y = 2;
console.log(`x = ${x}, y = ${y}`);
[x, y] = [y, x];
console.log(`x = ${x}, y = ${y}`);
MDN实际上将此作为其示例之一。
编辑:
不知何故,我错过了问题中的粗体文字。如果你绝对需要它是一个function,这种符合定义(并且绝对是一个笑话):
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}`);
要使 swap(a,b) 像在 C 中一样工作,您需要对变量的引用。它可以比上面的答案1更轻。只是
function swap(n, m) {
var temp = this[n];
this[n] = this[m];
this[m] = temp;
}
此函数中的 this 为window ,调用为swap('a', 'b')。当然,您可以使用逻辑或算术(对于int s)避免局部变量temp 。
我发现这种方法还不错(至少就我的目的而言):
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() 函数,因为它必须有权访问命名参数。这违背了“不要重复自己”的原则,但在某些情况下,如果这样可以简化算法逻辑,则可以接受复制和粘贴一些样板代码。
顺便说一句:我从中导出 this 的示例从swap() 返回了字符串,并依靠调用者将字符串转发给 eval: eval(swap('a','b'))
。这解决了范围问题,但使交换操作更容易出错——并且吸引力降低。
小心,该消息人士还警告说,这种方法可能会导致嘲讽。
如果你使用,穿越时空的吸血鬼会偷走你的信用卡eval()
吗?您应该自己决定,但这里有一些帮助:
我看到的最大问题是这可能相对较慢(取决于解释器如何管理缓存)。如果它对于您的目的来说太慢,那么不要使用它。