前提:交换变量的值,不借助第三个变量
普通方案
- 加减法
var a = 6, b = 9
a = a + b; // 15
b = a - b; // 将上式a代入得: a + b - b 结果为 a 得:6
a = a - b; // 将第一式的a,b带入a,第二式的b带入得:a + b - a,结果为 b 得:9
加减法方式不为一, 可以先减后加,效果一致
但是该方法注意越界问题,IEEE754标准得出数字的最大安全整数为 9007199254740991
可参考大佬文章# JavaScript 浮点数陷阱看详解
- 乘除法
var a = 6, b = 9
a = a * b; // 54
b = a / b; // 将上式a代入得: a * b / b 结果为 a 得:6
a = a / b; // 将第一式的a,b带入a,第二式的b带入得:a * b / a,结果为 b 得:9
乘除法方式不为一, 可以先除后乘,效果一致
依然会出现越界问题,原理同上
- 位运算
var a = 6, b = 9
a = a ^ b; // 15
b = a ^ b; // 将上式a代入得: a ^ b ^ b => a ^ 0 => a 得:6
a = a ^ b; // 将第一式的a,b带入a,第二式的b带入得:a ^ b ^ a => a ^ a ^ b => b,得:9
依然会出现越界问题,原理同上
骚操作
- 数组解构
var a = 'dddd', b = 9;
[a, b] = [b, a]; // 数组为[9, 'dddd'] a为9 b为'dddd'
可变式为:
var a = 'dddd', b = 9;
[a=b, b] = [,a]; // 数组为[empty, 'dddd'] a为9 b为'dddd'
- 数组法
var a = 'dddd', b = 9
a = [ b, b = a ][ 0 ]; // 数组为[9, 'dddd'] a为9 b为'dddd'
原理:利用数组缓存了b的值,并创建数组过程中完成了b的赋值。借用数组下标和赋值优先实现功能.
- 对象法
var a = 'dddd', b = 9
a = { b: b,a: b = a }.b; // 对象为{b: 9, a: "dddd"} a为9 b为'dddd'
原理:利用对象缓存数据,并创建对象过程中完成了b的赋值。
- 函数法
var a = 'dddd', b = 9
a = (function(){ b = arguments[0] ; return arguments[1]})(a, b); // a为9 b为'dddd'
原理:利用函数的arguments缓存数据。
- 原型法
var a = 'dddd', b = 9
Object.a = a;
a = b
b = Object.a
delete Object.a
// a为9 b为'dddd'
不删除声明的键值,容易污染原型,请谨慎使用
这里的的Object方法可以被替换成:Function, String, Date, Array...等等方法
总结
-
普通方案之
加减法、乘除法和位运算- 原理:通过值运算
- 优点:es5可用
- 缺点:
- 只能用于数字交换
- 有越界问题
-
骚操作之
数组法、对象法、函数法、原型法- 原理:通过js方式进行缓存数据得到
- 优点:
- es5可用
- 不限于数字
- 缺点:
- 代码不易理解
-
骚操作之
数组解构- 原理:es6数组解构方式交换彼此
- 优点:
- 高 ( 级 ) 大 ( 气 ) 上 ( 档次 )( es6 yyds )
- 写法最简洁且易理解
- 不限于数字
- 缺点:es5不支持
这里肯定推荐数组解构的方式,但是总有面试题要问,了解一下吧
文中如有错误,欢迎在评论区指正