# 数据类型-运算符

# 算数运算符

JavaScript 共提供 10 个算术运算符,用来完成基本的算术运算。

01. 加法运算符:x + y
02. 减法运算符: x - y
03. 乘法运算符: x * y
04. 除法运算符:x / y
05. 指数运算符:x ** y
06. 余数运算符:x % y
07. 自增运算符:++x或者 x++
08. 自减运算符:--x 或者 x--
09. 数值运算符: +x
10. 负数值运算符:-x

# 加法运算符 +

    1. JavaScript 允许非数值的相加。 弱类型
true + true; // 2
1 + true; // 2
    1. 如果是遇到字符串相加,这时加法运算符会变成连接运算符,返回一个新的字符串。
"a" + "bc"; // "abc"
"3" + 4 + 5; // "345"
3 + 4 + "5"; // "75"
    1. 对象的相加 相当的绕

默认调用 Object.prototype.valueOf() 然后调用 Object.prototype.toString()

var obj = { p: 1 };
obj + 2; // "[object Object]2"
var obj = { p: 1 };
obj.valueOf(); // { p: 1 }
var obj = { p: 1 };
obj.valueOf().toString(); // "[object Object]"

特例

//这里有一个特例,如果运算子是一个Date对象的实例,那么会优先执行toString方法。
var obj = new Date();
obj.valueOf = function () {
  return 1;
};
obj.toString = function () {
  return "hello";
};
obj + 2; // "hello2"
    1. 除了加法运算符,其他算术运算符(比如减法、除法和乘法)都不会发生重载。它们的规则是:所有运算子一律转为数值,再进行相应的数学运算。

# 余数运算符 %

(12 % 5) - // 2
  //运算结果的正负号由第一个运算子的正负号决定。
  (1 % 2); // -1
1 % -2; // 1
//所以,为了得到负数的正确余数值,可以先使用绝对值函数。
function isOdd(n) {
  return Math.abs(n % 2) === 1;
}
isOdd(-5); // true
isOdd(-4); // false

# 自增运算符 ++

var x = 1;
var y = 1;
console.log(x++); //1 先打印x后x=x+1
console.log(++x); //3 先x=x+1后打印x
console.log(++y); //2
console.log(y++); //2
console.log(y--); //3

# 数值运算符 +-

+true + // 1
  [] + // 0
  {}; // NaN
//连用两个负数值运算符要加上圆括号,否则就成了自减运算符
var x = 1;
console.log(-x); // -1
console.log(--x); //0
console.log(-(-x)); // 1

# 指数运算符 **

console.log(2 ** (3 ** 2)); // 相当于 2 ** (3 ** 2) = 2 ^ 9 = 512

# 赋值运算符 =

x += y; // 等同于 x = x + y
x -= y; // 等同于 x = x - y
x *= y; // 等同于 x = x * y
x /= y; // 等同于 x = x / y
x %= y; // 等同于 x = x % y
x **= y; // 等同于 x = x ** y

# 比较运算符

  1. 比较运算符用于比较两个值的大小,然后返回一个布尔值,表示是否满足指定的条件。
  • > 大于运算符

  • < 小于运算符

  • <= 小于或等于运算符

  • >= 大于或等于运算符

  • == 相等运算符

  • === 严格相等运算符

  • != 不相等运算符

  • !== 严格不相等运算符

  • 字符串按照字典顺序进行比较。

  • 如果两个运算子都是原始类型的值,则是先转成数值再比较。

  • 对象转换成原始类型的值,算法是先调用valueOf方法;如果返回的还是对象,再接着调用toString方法

  1. 相等运算符

    1. 原始类型的值会转换成数值再进行比较。

    2. 复合类型 与原始类型的值比较时,复杂类型转换成原始类型的值,再比较。

    3. undefinednull与其他类型的值比较时,结果都为false,它们互相比较时结果为true

    4. " \t\r\n " == 0; // true
      
  2. 严格相等运算符

    1. 如果两个值的类型不同,直接返回false
    2. 同一类型值相同就返回true,值不同就返回false
    3. 复合类型 (对象、数组、函数) 比较时,比较它们是否指向同一个地址

# 布尔运算符

    1. 取反运算符:(!)
  • 注意下面这些这些值取反后为 true

undefined null false
NaN ('')
    1. 且运算符 :(&&) 往往用于多个表达式的求值 注意返回的是值,不是布尔值
  • 如果第一个运算子的布尔值为true,则返回第二个运算子的值

  • 如果第一个运算子的布尔值为false,则直接返回第一个运算子的值

  • 多个连用时返回第一个布尔值为false的表达式 ,全为true则返回最后一个表达式的值

    1. 或运算符:(||
  • 如果第一个运算子的布尔值为true,则返回第一个运算子的值 。

  • 或运算符常用于为一个变量设置默认值。

saveText(this.text || "");
    1. 三元条件运算符(?:
  • JavaScript 语言唯一一个需要三个运算子的运算符。如果第一个表达式的布尔值为true,则返回第二个表达式的值,否则返回第三个表达式的值。

"t" ? "hello" : "world"; // "hello"
0 ? "hello" : "world"; // "world"

# 位运算符

  1. 位运算符直接处理每一个比特位 , 好处是速度极快,缺点是很不直观。

  2. 有一点需要特别注意,位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行。

  3. 位运算符可以用作设置对象属性的开关。

  4. 异或运算带来的神奇操作:互换两个变量的值的最快方法

(a ^= b), (b ^= a), (a ^= b); //b = b^a^b = a , a = a^b^b^a^b = b;
运算符 符号 含义
位与运算符 & 示若两个二进制位都为 1,则结果为 1,否则为 0。
位或运算符 | 表示若两个二进制位都为0,则结果为0,否则为1
位反运算符 ~ 表示对一个二进制位取反。
异或运算符 ^ 表示若两个二进制位不相同,则结果为 1,否则为 0。
左移运算符 << 向左移动一个二进制位
右移运算符 >> 向右移动一个二进制位
0 & 3; //  00 & 11 --> 00 --> 0
0 | 3; //  00 | 11 --> 11 --> 3
~3; // 可以简单记忆成,一个数与自身的取反值相加,等于-1。--> -4
~~3; // 对一个整数连续两次二进制否运算,得到它自身。--> 3
0 ^ 2; //  00 ^ 10 --> 10
4 << 1; //  100 << 1 --> 1000 --> 8
4 >> 1; //  100 >> 1 --> 10 --> 2
-4 << 1; //  10100 << 1 --> 11000--> -8
-4 >> 1; //  10100 >> 1 --> 10010--> -2

# 类型判断运算符

JavaScript 有三种方法,可以确定一个值到底是什么类型:

  • typeof 运算符 可以返回一个表示传入值数据类型的字符串。例如 console.log(typeof 1);
  • instanceof 运算符 用于检测构造函数的 prototype 属性 例如 instance of Array 可以判断是否是数组,检查原型链
  • toString() 方法 可将一个对象转换为字符串,并返回结果。