所以给定一个函数
function foo( a, b ) {
}
现在,如果我想交换参数a
和b
的值,我可以这样写:
var t = a;
a = b;
b = t;
然而,这是一个丑陋的模式 - 它需要三个语句(三行代码),加上一个局部变量。现在,我可以承担三个声明,但必须声明那个烦人的辅助变量?我想避免这种情况。
那么,有什么更好的方法呢? (更好的代码行(可能是单行代码),或者不声明局部变量。)
我想出了这个:
(function ( t ) { a = b; b = t; })( a ); // swap a and b
现场演示: http://jsfiddle.net/J9T22/
那么,你能想出什么?
答案 0 :(得分:14)
使用它的功能?的严重吗
最简单的往往是最好的:
var t = a;
a = b;
b = t;
如果您使用它,例如对于服务器端JS(即您只需要支持一个 JavaScript引擎),您也可以使用解构赋值语法:
[a, b] = [b, a]
答案 1 :(得分:8)
这是一个有趣的小练习。
你可以这样做:a=[b][b=a,0]
var a='a';
var b='b';
a=[b][b=a,0];
alert(a + ', ' + b); // "b, a"
同样来自我的+1,无视仇敌;)
......哦等等!这个不是是一个有趣的小练习,但实际上是用于现实世界吗?那么你最好不要这样做,因为它的可读性低于var t = a; a = b; b = t!
a=[b][b=a,0]; // wth?
var t=a; a=b; b=t; // ahhh so readable!
但是,不,严肃地说,这样做实际上给你带来了比必须创建另一个变量更好的好处,因为你可以做到这一点。 Var声明通常不能成为普通语句的一部分,因此尝试执行(var t=a; a=b; b=t)
之类的操作只会抛出一个SyntaxError,但(a=[b][b=a,0])
计算结果为a
,这可能很有用。
讨论这样的事情很有意思,因为在我们的生产代码中,以非常规的方式做事可能不受欢迎,这是学习语言的好方法。那(我认为)就是SO的全部意义所在。我休息一下。
答案 2 :(得分:5)
在Mozilla的Javascript 1.7中,您可以[a, b] = [b, a]
。
答案 3 :(得分:3)
我读过你不应该这样做但是......
a=5;
b = 7
//add parenthesis to make this do what it should in one line
a ^= b;
b ^= a;
a ^= b;
他们现在应该拥有彼此的价值观。 [编辑]根据pointedears的描述,这不符合规定,但这里描述了它是如何工作的...但是,正如已经陈述的(由其他人)坚持最简单的。没有理由这样做,你不会注意到任何性能提升,你的代码将变得不那么可读。
http://en.wikipedia.org/wiki/XOR_swap_algorithm
在这里它正在行动...... http://jsfiddle.net/nHdwH/
答案 4 :(得分:3)
如果您仅允许Mozilla或future ES6 stuff,则可以使用解构分配:
[a,b] = [b,a]
如果最大的担忧是环境污染可变,你可以借用arguments
对象。
arguments[arguments.length] = a;
a = b;
b = arguments[arguments.length];
但这有点长。
或者您可以将对象分配给现有参数:
a = {a:a,b:b};
b = a.a;
a = a.b;
function foo( a, b ) {
a = {a:a,b:b};
b = a.a;
a = a.b;
console.log(a,b); 'baz' 'bar'
}
foo('bar','baz');
或者删除像这样的东西:
a = {b:b,a:(b=a)};
a = a.b;
或者直到一行:
a = {b:b,a:(b=a)}.b;
目前在“严格模式”支持的实现中,您可以执行此操作(如果您实际上是以“严格模式”运行):
a = b; b = arguments[0];
这是因为对形式参数的更改对arguments
对象没有影响,反之亦然。
答案 5 :(得分:1)
交换两个参数值的更好方法是什么?
没有“更好”的方式,只有一些渐渐变得模糊不清的方式。
有些人可能认为其他方法“聪明”,我想其中有些方法是,但我不想与任何认为他们实际上“更好”的人合作,因为我不希望看到这样的方法在实际项目代码中出现。
“聪明”数学方法只有在你假设整数值时才有效,所以在我看来,由于你没有指定类型,所以它们是错误的。
如果您发现丑陋的三个陈述,您可以这样做:
var t;
t = a, a = b, b = t;
是的,它实际上是一样的,但至少它将交换代码全部放在同一行。
(尽管如此,我认为如果没有浏览器支持,[a, b] = [b, a];
会“更好”。)
答案 6 :(得分:0)
如果值是整数,那么您可以使用算术来完成工作:
function foo( a, b ) {
a = -(b = (a += b) - b) + a;
console.log(a);
console.log(b);
}
foo(1,2);
答案 7 :(得分:0)
a=[a,b];
b=a[0];
a=a[1];
这只使用变量a和b,但它会创建一个数组, 这比临时变量更重要。
使用临时变量。
var t = a; A = B; B =吨;
另一个理智的支持。
答案 8 :(得分:0)
我略微不同意其他人,这可能很有用。但是,将其内联定义为坏,坏,坏,坏,坏。如果你打算这样做,它应该是一个更高阶的函数:
function flip(fn) {
return function(a, b) {
return fn.call(null, b, a);
};
}
例如:
function log() {
console.log.apply(console, arguments);
}
flip(log)(1, 2); // 2 1
现在这看起来很愚蠢,但是当你进行映射/缩减/迭代等时,这种事情经常发生。说你有一些功能:
function doSomeStuff(index, value) {
// complex stuff happening here
}
一个数组:
var arr = ["foo", "bar", "etc"];
如果您要使用,例如,在此数组上映射并需要调用doSomeStuff
,您必须手动滚动此功能:
arr.map(function(value, index) {
return doSomeStuff(index, value);
});
虽然你可以说这并不坏,但它会分散你想要做的事情(只是称之为该死的功能!)。有了这个更高阶的函数,它可以简化为:
arr.map(flip(doSomeStuff));
如果您想要更完整的翻转功能,您可以:
function flip(fn) {
return function() {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, args.reverse());
};
}
现在:
flip(log)(1,2,3,4,5); // 5 4 3 2 1
答案 9 :(得分:0)
我认为在现实世界中,人们会希望这种交换是有条件的。
[a,b] = c? [a,b] : [b,a]
你也可以用[a,b] [+ c]替换a的所有实例,用[b,a] [+ c]替换所有b的实例,如:
arr.sort( (a,b) => [a,b][+c] - [b,a][+c] )
或只是有一个函数来调用函数:
swapMyFunction = (a,b) => myFunction(b,a)