3

与内联工作相比,swap() 函数会产生更简洁的代码 ( DRY )。不幸的是,以下函数什么也没做,因为在 JavaScript 中参数总是按值传递

function swap(a,b) { var temp=a; a=b; b=temp; }

有没有办法编写一个函数来完成这个尝试,特别是对于数值?

我对这个相关问题的答案印象不深。
这个答案有正确的想法,但不处理一般情况。

4

4 回答 4

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')
于 2013-09-15T22:03:21.173 回答
1

使用 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}`);

于 2018-01-13T01:55:56.897 回答
-2

要使 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 。

于 2015-10-02T21:51:01.227 回答
-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() 函数,因为它必须有权访问命名参数。这违背了“不要重复自己”的原则,但在某些情况下,如果这样可以简化算法逻辑,则可以接受复制和粘贴一些样板代码。


顺便说一句:我从中导出 this 的示例从swap() 返回了字符串,并依靠调用者将字符串转发给 eval: eval(swap('a','b'))。这解决了范围问题,但使交换操作更容易出错——并且吸引力降低。

小心,该消息人士还警告说,这种方法可能会导致嘲讽


如果你使用,穿越时空的吸血鬼会偷走你的信用卡eval()吗?您应该自己决定,但这里有一些帮助:

我看到的最大问题是这可能相对较慢(取决于解释器如何管理缓存)。如果它对于您的目的来说太慢,那么不要使用它。

于 2013-09-15T22:39:32.683 回答