JavaScript运算符
重要通知
。
基本概况
delete
console.log(void 0); // undefined
// delete仅仅删除其值,但是会保留存储空间
const data = [{ name: 'wang', count: 1}, { name: 'zhang', count: 1}];
delete data[2];
console.log(data.length); // 2
相等判断符
JS判断两个数组或对象是否相等
equal
判断两个对象是否完全内容相等(非引用相等),复杂对象,将会递归判断。
判断规则:
两个对象全等(bj1 === obj2),则相等
两个对象都是 null 或都是 undefined,则相等
两个对象的数据类型不一致,则不相等
两个对象都是数组
数组长度不一致,则不相等
按顺序比较相同索引的元素,递归调用equal判断,若遇到不相等的元素,则不相等
当所有相同索引元素都完全内容相等,则相等
两个对象都是字面量对象
键值对个数不一致,则不相等
按相同 key 获取值,递归调用equal判断,若遇到不相等的值,则不相等
当所有相同 key 的值都完全内容相等,则相等
function isEqual(a, b) {
return true;
}
JS判断两个数组是否相等?
const arr1 = [0, 10, 7, 3, 15];
const arr2 = [0, 10, 7, 3, 15];
console.log(arr1 === arr2); // false
console.log(arr1.toString() === arr2.toString()); // true
JS判断两个对象是否相等?
使用lodash深度对比/比较/对比出2个对象之间的差异
/**
* Deep diff between two object, using lodash
* @param {Object} object Object compared
* @param {Object} base Object to compare with
* @return {Object} Return a new object who represent the diff
*/
function difference(object, base) {
function changes(object, base) {
return _.transform(object, function(result, value, key) {
if (!_.isEqual(value, base[key])) {
result[key] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
}
});
}
return changes(object, base);
}
var a = {name:89757,date:{year:2017}}
var b = {name:89757,date:{year:2017,month:3}}
difference(a,b)
//{date:{month:3}}
运算符
!!强制转换符
in运算符
[~] 判断变量是否为对象属性 let dot = {a: 100, b: 200}; var mat = 'a'; if (mat in dot) { console.log('true'); } else { console.log('false'); } [~] 判断变量是否属于数组上标与下标之间 let arr = [0, 1, 2]; let index = 3; if (index in arr) { console.log('true'); } else { console.log('false'); }
void运算符
var a = 1; var b = 2; document.write("a+b =" + (a + b) + "
"); //输出:a + b = 3 document.write("void(a + b) = " + void(a + b) + "
"); //输出:void(a + b) = undefined
instanceof运算符
功能:检测某实例是否为某对象的实例
案例
var obj = new Date(); if (obj instanceof Date) { console.log('true'); } else { console.log('false'); } console.log(obj instanceof Array); //false
算术运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
加法运算符 + 对两个数字型的操作数进行相加运算,返回两个操作数之和
减法运算符 - 对两个数字型的操作数进行相减运算,返回第一个操作数减去第二个操作数之差
乘法运算符 * 对两个数字型的操作数进行相乘运算,返回两个操作数之积
除法运算符 / 对两个数字型的操作数进行相除运算,返回第一个操作数除以第二个操作数的值
模运算符 % 对两个数字型的操作数进行相除运算,返回第一个操作数除以第二个操作数之后的最后余数
负号运算符 - 将一个数字进行取反操作,即将一个正数转换成相应的负数或将一个负数转换成相应的正数
正号运算符 +
递增运算符 ++ 将操作数进行递增操作,即每次增加1
递减运算符 -- 将操作数进行递减操作。即每次减少1
--------------------------------------------------------------------------------------------------------------------------------------
关系运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
相等 == 比较两个操作数的值是否相等;如果相等,返回true;如果不相等,返回false;
等同 === 比较两个操作数的值与数据类型是否相等;如果相等,返回true;如果不相等,返回false;
不等 != 比较两个操作数的值是否不相等;如果不相等,返回true;如果相等,返回false;
不同 !== 比较两个操作数的值与数据类型是否不相等;如果不相等,返回true;如果相等,返回false;
小于 < 当第一个操作数小于第二个操作数时,返回true;反之,返回false;
大于 > 当第一个操作数大于第二个操作数时,返回true;反之,返回false;
小于或等于 <= 当第一个操作数小于或等于第二个操作数时,返回true;反之,返回false;
大于或等于 > 当第一个操作数大于或等于第二个操作数时,返回true;反之,返回false;
in in 对于对象,in判断对象与属性的布尔关系;对于数组,in判断数组下标是否存在(数组下标从0开始计算);
为真时,返回true;为假时,返回false。
instanceof instanceof 对于类,检查对象是否为某个构造函数的实例;若为真,返回true;若为假,返回false;
--------------------------------------------------------------------------------------------------------------------------------------
字符串运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
连接 + 连接两个字符串,生成一个新的字符串
--------------------------------------------------------------------------------------------------------------------------------------
赋值运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
赋值 = 给一个变量赋值
--------------------------------------------------------------------------------------------------------------------------------------
逻辑运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
与 && 左右两个操作数同时都为真时,返回true;反之,返回false;
或 || 左右两个操作数同时为真或其中一个为真时,返回true;反之,返回false;
非 ! 操作数为假时,返回true;反之,返回false;
!! 强制转为Boolean类型,若不为true,则转换为false --------------------------------------------------------------------------------------------------------------------------------------
逐位运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
与 & 当两个操作数中相对应的位都为1时,返回1;反之,返回0;
或 | 当两个操作数中相对应的位都为1或其中一个为1时,返回1;反之,返回0;
异或 ^ 当两个操作数中相对应的位不同时,返回1;反之,返回0;
非 ~ 将操作数中的所有位取反,对于一个带符号的整数进行逐位非运算,相当于将该整数改变符号后再减1
左移 <<
带符号的右移 >>
用0补足的右移 >>>
--------------------------------------------------------------------------------------------------------------------------------------
特殊运算符
--------------------------------------------------------------------------------------------------------------------------------------
运算符名称 符号 作用
--------------------------------------------------------------------------------------------------------------------------------------
条件运算符 ?: 条件表达式 ? 执行语句1 : 执行语句2;若表达式成立,执行语句1;反之,执行语句2
new new 定义一个新的内置对象实例,如var myDate = new Date();
void void 让操作数进行运算,但是却舍弃运算之后结果
typeof typeof 返回操作数的数据类型
对象属性存取 . 第一个操作数必须是对象或对象的实例名,第二个操作数必须是对象的属性名
数组元素存取 [] 该符号之前必须为数组名称,符号之间为数组下标
delete delete 用来删除变量、对象的属性或数组中的元素,例如:delete 对象名;delete 对象名.属性名;delete 数组
[索引]; delete 变量名
逗号 , 分隔两个操作数
函数调用 () 调用函数
this this 代表当前对象
--------------------------------------------------------------------------------------------------------------------------------------
运算符与优先级
位运算(&、|、^、~、>>、<<):https://www.runoob.com/w3cnote/bit-operation.html
指数运算 | 求幂运算符是是右结合的: a ** b ** c 等于 a ** (b ** c).
n ** n | 2 ** 2 = 4 | 2 ** 3 = 8 自增:count++ | --count | count += 1; | count -= 1; | count *= 1;
in 与 instanceof 运算符
in:检测对象中是否存在指定的属性。 instanceof:判断指定对象是否存在于某个类中。
// in
const inResult = property in Object;
// instanceof
const inofResult = obejct in Class;
运算符和运算符的优先级
赋值运算符(Assignment operators) 比较运算符(Comparison operators) 算数运算符(Arithmetic operators) 位运算符(Bitwise operators) 逻辑运算符(Logical operators) 字符串运算符(String operators) 条件(三元)运算符(Conditional operator) 逗号运算符(Comma operator) 一元运算符(Unary operators) 关系运算符(Relational operator)
+ 运算符
// :
console.log(+'0xFF'); // 16进制转换: 255
// 获取当前的时间戳,相当于`new Date().getTime()`:
+new Date();
// 比 parseFloat()/parseInt()更加安全的解析字符串
parseInt("1,000"); // -> 1, not 1000
+"1,000"; // -> NaN, much better for testing user input
parseInt("010"); // -> 8, because of the octal literal prefix
+"010"; // -> 10, `Number()` doesn't parse octal literals
//一些简单的缩写比如: if (someVar === null) {someVar = 0};
+null; // -> 0;
// 布尔型转换为整型
+true; // -> 1;
+false; // -> 0;
//其他:
+”1e10″; // -> 10000000000
+”1e-4″; // -> 0.0001
+”-12″; // -> -12:
算术运算符
==相等运算符
相等运算符(==和!=)使用抽象相等比较算法比较两个操作数。
- 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true。
- 如果一个操作数是null,另一个操作数是undefined,则返回true。
- 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
- 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
- 如果操作数之一是Boolean,则将布尔操作数转换为 1 或 0。
- 如果是true,则转换为1。
- 如果是 false,则转换为0。
- 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。
- 如果操作数具有相同的类型,则将它们进行如下比较:
- String:true仅当两个操作数具有相同顺序的相同字符时才返回。
- Number:true仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false。
- Boolean:true仅当操作数为两个true或两个false时才返回true。
===全等运算符
全等运算符(===和 !==)使用全等比较算法来比较两个操作数。
- 如果操作数的类型不同,则返回 false。
- 如果两个操作数都是对象,只有当它们指向同一个对象时才返回 true。
- 如果两个操作数都为 null,或者两个操作数都为 undefined,返回 true。
- 如果两个操作数有任意一个为 NaN,返回 false。
- 否则,比较两个操作数的值:
- 数字类型必须拥有相同的数值。+0 和 -0 会被认为是相同的值。
- 字符串类型必须拥有相同顺序的相同字符。
- 布尔运算符必须同时为 true 或同时为 false。
==与===区别
全等运算符不尝试类型转换。相反,如果操作数的类型不同,== 运算符会在比较之前尝试将它们转换为相同的类型。
- a == 1 && a == 2
const a = {
i: 0,
valueOf() {
return ++this.i;
}
};
if (a == 1 && a == 2) {
console.log('equal');
}
- 相等运算符
const a = { b: 40 };
const b = { key: 'b' };
const c = { key: 'c' };
a[b] = 41;
a[c] = 42;
console.info(a[b]); // 42
- 比较字符串和String对象
const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");
console.log(string1 == string2); // true
console.log(string1 === string2); // true
console.log(string1 == string3); // true
console.log(string1 === string3); // false
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true
- 比较字符串和String对象
console.log('1' === '1'); // true
console.log(String('1') == String('1')); // true
console.log(String('1') === String('1')); // true
console.log(new String('1') == new String('1')); // true
console.log(new String('1') === new String('1')); // true
- 比较日期和字符串
const d = new Date('December 17, 1995 03:24:00');
const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
console.info(d, s);
console.info(d == s); // true
console.info(d === s); // false
- 比较对象
const object1 = { name: "hello" }
const object2 = { name: "hello" }
console.log(object1 == object2); // false
console.log(object1 === object2); // false
console.log(object1 === object1); // true
赋值运算符
比较运算符
位运算符
运算符经典示例
空值合并运算符( ?? )、空值赋值运算符( ??= )、可选链操作符( ?. )、(!.)、三元运算符( ?: )
const a = null;
const b = undefined;
const c = 0;
const ca = -1;
const cb = 1;
const d = false;
const da = true;
const e = '';
const ea = 'vite';
const f = [];
const fa = ['css', 'html', 'javascript'];
const g = {};
const ga = { name: 'vue' };
const h = Symbol;
const ha = Symbol('111');
const content = '标准内容';
var input = '输入';
var output;
// 空值合并运算符(??) 过滤null或undefined
console.info(a ?? content, b ?? content, c ?? content, e ?? content); // 标准内容 标准内容 0 ''
// 空值赋值运算符(??=) 仅仅??=左侧条件为null或undefined时才赋值
console.info(input ??= c); // 输入
// 可选链操作符(?.) 在无需对对象链是否存在有效的情况下允许读取位于连接对象链深处的属性值。
console.info(a?.name);
// TS非空断言操作符(!.) TypeScript also has a special syntax for removing null and undefined from a type without doing any explicit checking. Writing ! after any expression is effectively a type assertion that the value isn’t null or undefined
console.info(a!.name);
// 非(!) 仅仅对null、undefined、0、false、''进行断言,而[]、{}、Symbol(null)、Symbol(undefined)、Symbol('')等无效
console.info(!a, !b, !c, !d, !e, !f, !g, !ha); // true true true true true false false false
运算符优先级

位运算符
JavaScript 将数字存储为 64 位浮点数,但所有按位运算都以 32 位二进制数执行。在执行位运算之前,JavaScript 将数字转换为 32 位有符号整数。执行按位操作后,结果将转换回 64 位 JavaScript 数。
- 示例:https://www.w3school.com.cn/js/js_bitwise.asp
- 不同进制转换工具:https://tool.lu/hexconvert/
--------------------------------------------------------------------------------------------------------------------------
Operator Usage Description
--------------------------------------------------------------------------------------------------------------------------
按位与 AND a & b 在a,b的位表示中,每一个对应的位都为1则返回1, 否则返回0.
按位或 OR a | b 在a,b的位表示中,每一个对应的位,只要有一个为1则返回1, 否则返回0.
按位异或 XOR a ^ b 在a,b的位表示中,每一个对应的位,两个不相同则返回1,相同则返回0.
按位非 NOT ~ a 反转被操作数的位。
左移 shift a << b 将a的二进制串向左移动b位,右边移入0.
算术右移 a >> b 把a的二进制表示向右移动b位,丢弃被移出的所有位.(译注:算术右移左边空出的位是根据最高位是0和1来进行填充的)
无符号右移 (左边空出位用0填充) a >>> b 把a的二进制表示向右移动b位,丢弃被移出的所有位,并把左边空出的位都填充为0
--------------------------------------------------------------------------------------------------------------------------
- 代码示例
--------------------------------------------------------------------------------------------------------------------------
操作 结果 等同于 结果
5 & 1 1 0101 & 0001 0001
5 | 1 5 0101 | 0001 0101
5 ^ 1 4 0101 ^ 0001 0100
~ 5 10 ~0101 1010
5 << 1 10 0101 << 1 1010
5 >> 1 2 0101 >> 1 0010
5 >>> 1 2 0101 >>> 1 0010
--------------------------------------------------------------------------------------------------------------------------