交换变量的n种方式

440 阅读3分钟

前提:交换变量的值,不借助第三个变量

普通方案

  1. 加减法
    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 浮点数陷阱看详解

  1. 乘除法
    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

乘除法方式不为一, 可以先除后乘,效果一致

依然会出现越界问题,原理同上

  1. 位运算
    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

依然会出现越界问题,原理同上

骚操作

  1. 数组解构
    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'
  1. 数组法
    var a = 'dddd', b = 9
    a = [ b, b = a ][ 0 ]; // 数组为[9, 'dddd'] a为9 b为'dddd'

原理:利用数组缓存了b的值,并创建数组过程中完成了b的赋值。借用数组下标和赋值优先实现功能.

  1. 对象法
    var a = 'dddd', b = 9
    a = { b: b,a: b = a }.b; // 对象为{b: 9, a: "dddd"} a为9 b为'dddd'

原理:利用对象缓存数据,并创建对象过程中完成了b的赋值。

  1. 函数法
    var a = 'dddd', b = 9
    a = (function(){ b = arguments[0] ; return arguments[1]})(a, b); // a为9 b为'dddd'

原理:利用函数的arguments缓存数据。

  1. 原型法
    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...等等方法

总结

  1. 普通方案之 加减法乘除法位运算

    • 原理:通过值运算
    • 优点:es5可用
    • 缺点:
      • 只能用于数字交换
      • 有越界问题
  2. 骚操作之 数组法对象法函数法原型法

    • 原理:通过js方式进行缓存数据得到
    • 优点:
      • es5可用
      • 不限于数字
    • 缺点:
      • 代码不易理解
  3. 骚操作之 数组解构

    • 原理:es6数组解构方式交换彼此
    • 优点:
      • 高 ( 级 ) 大 ( 气 ) 上 ( 档次 )( es6 yyds )
      • 写法最简洁且易理解
      • 不限于数字
    • 缺点:es5不支持

这里肯定推荐数组解构的方式,但是总有面试题要问,了解一下吧

文中如有错误,欢迎在评论区指正