是否可以在JavaScript中编写数字swap()函数?

时间:2013-09-15 21:44:54

标签: javascript swap

swap()函数会产生比内联工作更清晰的代码(DRY)。不幸的是,以下函数没有任何结果,因为JavaScript参数中的始终是按值传递

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

有没有办法编写一个函数来完成正在尝试的内容,特别是对于数值?

我对this related question的答案印象不深 This answer有正确的想法,但不处理一般情况。

4 个答案:

答案 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(),时间旅行的太空吸血鬼会偷走您的信用卡吗?你应该自己决定,但这里有一些帮助:

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