JavaScript表达式与运算符

1、对于引号的使用:

数字、布尔、对象、数组这类原生类型不需要引号。

只有键名带空格、横杠、关键字、特殊符号时,引号才强制不能省。

var person = {"name":"Jack", "age":18, "id":89757};

name / "age" / id 是属性键(属性名)

属性键规则和值不一样:

正常英文单词、合法标识符(name、age、id):可加引号、可不加引号,效果完全一样

name:"Jack" 等价 "name":"Jack"

"age":18 等价 age:18

这两个代码运行的区别:

var person = {name:"Jack","age":18,id:89757};

console.log(person.name1);

对象 person 里只有 name、age、id 三个属性,不存在 name1 属性

访问对象上未定义的属性,返回:undefined

var person = {name:"Jack","age":18,id:89757};

console.log(person1.name);

代码中只声明了变量 person,完全没有定义变量 person1

直接读取未声明的变量,浏览器 / 控制台会抛出引用错误:

Uncaught ReferenceError: person1 is not defined

总结: 属性不存在:对象。不存在的属性 → undefined(不会报错)

变量不存在:直接写一个从没 var/let/const 声明的变量 → 直接抛引用错误

①加性运算符

NaN:不是一个有效数字(Not a Number),只要计算乱套了就会出 NaN

只要任意一边是 NaN → 结果一定是 NaN

大白话:一堆数字里混了一个 "无效数字",整体计算直接作废,结果全是无效数字

举例:正无穷 + 负无穷 = NaN

一个无限大、一个无限小,两者没法抵消算出固定值,直接判定无效数字

好比:无限大减去无限大,没有固定答案

注意:如果有一边是字符串,加法会变成「拼接文字」,不再走这套数字加法规则 举例: 10 + "20" // "1020" 字符串拼接,不是数字30

极简记忆口诀:

沾 NaN 必出 NaN;

同号无穷相加不变号;

正负无穷一对碰直接变 NaN;

零相加:俩负零得负零,其余搭配全是正零。

②减性运算符

极简记忆口诀:

遇 NaN 必得 NaN;

同无穷相减(∞−∞ /-∞−-∞)必出 NaN;

异无穷相减:∞减负∞得∞,-∞减∞得 -∞;

零相减,只有负零减正零才得负零,其余大多归正零。

加/减无穷区别:

加法:同无穷相加不变;正负无穷碰一起直接 NaN

减法:同无穷相减直接 NaN;正负无穷相减会叠加放大(∞减负∞=∞;-∞减∞=-∞)

额外小提示(和加法区分):

加法里 ∞ + (-∞) = NaN

减法里 ∞ - (-∞) = ∞ 符号逻辑不一样,别记混。

而且减法永远不会字符串拼接,不像加号碰到文字会拼文本;只要用减号,一定会强制转数字计算。

例:"20" - 10 → 10(自动把 "20" 转数字 20 再减)

③递增和递减运算符:

可以作用于非数字变量,自动隐式转换

转换规则:先用Number()转值,再 ±1

字符串数字:

let s = "10";

s++; // "10"→10 → 11,s最终变成数字11

布尔值: true=1、false=0

let flag = true;

flag++; // 1+1=2

let f = false;

f--; //0-1=-1

undefined:转 Number 是 NaN,自增后依旧 NaN
null:转 Number 是 0

let n = null;

n++; //0+1=1

JS 只有一种 Number 类型(64 位浮点数),小数可以直接 ++/--

let x = 2.5;

x++; //3.5

④乘法运算符:

乘法不会像加号那样拼接字符串,遇到非数字一律先用 Number() 转成数字再计算,转失败得到 NaN

字符串数字

"5" * "2"; //10 字符串自动转5、2相乘

"10" * 3; //30

纯文本字符串(转不成数字)

"abc" * 2; //NaN

"12a" * 4; //NaN

布尔值

true=1、false=0

true * 6; //1*6=6

false * 9; //0*9=0

null / undefined
null 转数字是 0
undefined 转数字是 NaN

null * 7; //0*7=0

undefined * 3; //NaN

速记口诀:

沾 NaN 必出 NaN;

无穷乘大数留无穷,无穷乘 0 直接变 NaN;

正负 0 相乘,正负看乘数符号;

遇文本不拼接,全部强制转数字,转失败就是 NaN。

⑤除法运算符:

JS 除法不会像 C 语言整数相除自动取整,会保留小数结果

除法没有字符串拼接,所有非数字操作数自动用Number()转为数字再计算,转换失败则结果 NaN

C:两个 int 相除,直接舍弃小数、向下取整;7/2=3

JS:不分 int/float,统一浮点除法;7/2=3.5,想要取整要用Math.floor()、parseInt()

C:整数除以 0直接程序崩溃报错;浮点才会出现无穷 / NaN

JS:任何数字除以 0 不会崩溃,返回 Infinity/-Infinity;0/0 固定 NaN

速记口诀:

遇 NaN 必出 NaN;

正数除 0 正无穷,负数除 0 负无穷;0 除 0 直接 NaN;

无穷除以无穷算不出,结果归 NaN;

字符串不拼接,全部强制转数字;

和 C 不一样,整数相除保留小数,不会自动截断。

⑥求模运算符:

任一操作数为 NaN → 结果一定 NaN
四则通用规则,混入无效数字直接失效

NaN % 5 // NaN

9 % NaN // NaN

NaN % NaN // NaN

Infinity 无穷大运算规则:

无穷大 % 任意有限数字 = NaN

任意有限数字 % Infinity = 自身原值

Infinity % Infinity = NaN

Infinity % 10 // NaN

25 % Infinity // 25

-18 % Infinity // -18

Infinity % -Infinity // NaN

余数符号 = 被除数符号:

-10 % 3 // -1 被除数-10是负,余数负

10 % -3 // 1 被除数10是正,余数正

-10 % -3 // -1 被除数负,余数负

0、正负零运算规则:

非 0 数字 % ±0 → NaN(除数不能是 0 系列)

±0 % 任意非 0 数字 → 和被除数同号的 0

8 % 0 // NaN

-5 % -0 // NaN

+0 % 6 // +0

-0 % 9 // -0

% 不会拼接字符串,全部自动用Number()转数字计算,转换失败 = NaN

浮点数可以直接取模(JS 全是浮点):

C 语言 int 不能带小数取模,JS 支持小数运算

5.5 % 2 // 1.5

4.2 % 1 // 0.2

-3.6 % 2 // -1.6

相等操作符

严格相等 ===
规则:

先对比数据类型,类型不一样直接返回 false

类型相同,再对比值;值完全一致才返回 true

不做任何自动类型转换

特殊值严格相等规则:

NaN === 任何值 全是 false,包括 NaN === NaN → false

判断 NaN 只能用 Number.isNaN(值)

+0 === -0 → true(正负零严格相等)

对象 / 数组:对比内存地址,不是里面内容

宽松相等 ==(会自动隐式转类型,坑多尽量少用)
核心逻辑:

两边类型不同时,JS 自动调用Number()把两边转成数字,再对比值;有一套固定转换规则。

null 和 undefined 特殊配对

null == undefined → true;除此之外它们和任何值 == 都是 false

严格不等 !==类型不同直接 true
宽松不等 != 同样会自动转类型

null/undefined在C和js中的区别:

C 没有undefined;C 的NULL本质是宏0,NULL == 0为 true;

JS 里null == 0是 false,null==undefined才 true

C:数组名是地址,arr1 == arr2对比内存地址;结构体不能直接用 == 对比,要逐个成员判断

JS:对象 / 数组无论== / ===全对比引用地址,不对比内容

关系操作符:

任一操作数是 NaN → 结果一定是 false

只要有无效数字参与比较,全部返回 false

NaN > 1 // false

5 < NaN // false

NaN >= NaN // false

Infinity > Infinity // false

-Infinity < -Infinity // false

正负 0 互相比较完全相等:

+0 和 -0 在大小对比里无区别

+0 > -0 // false

+0 >= -0 // true

两边都是字符串: 不转数字,按ASCII 字符编码逐位对比

一边 / 两边不是字符串:全部调用Number()转为数字再对比大小

速记口诀:

遇 NaN,所有大小比较全 false;

两字符串比 ASCII 编码,其余组合统一转数字;

Infinity 最大,-Infinity 最小;±0 大小相等;

禁止连续连写比较,必须用&&拆分;

C 比 JS 严格太多,字符串不能直接大小对比。

逻辑操作符:

! 逻辑非(取反): 一元运算符,单个值取真假反向

&& 逻辑与: 两边都真,整体才真;一假即假

|| 逻辑或: 一边真,整体就真;一真即真

连续两个 !! 等价强制转布尔(常用小技巧)!!5 // true 等价 Boolean(5)

&& 逻辑与(短路与)
求值规则(短路核心

左边为假值:直接返回左边原值,右边代码完全不执行(短路)

左边为真值:返回右边原值

|| 逻辑或(短路或)
求值规则

左边为真值:直接返回左边原值,右边短路不执行

左边为假值:返回右边原值

优先级顺序:

! 最高 > && 次之 > || 最低

易踩坑易错点:

空数组\[\]、空对象{}是真值:

\[\] && 123 //123(左为真,返回右)

\[\] || 456 //\[\](左为真,返回左)

"0"字符串是真值,只有数字 0 是假:

"0" || 99 //"0"

0 || 99 //99

不能用 && || 替代 if 做复杂多分支,但适合简单默认赋值、条件执行

赋值操作符

基础赋值 =

解构赋值(JS 独有,C 语言没有)

快速把数组、对象里的值批量提取给变量

1. 数组解构

let arr = 10,20,30;

let x,y,z = arr;

// x=10,y=20,z=30

// 跳过元素

let m,,n = arr; // m=10,n=30

2. 对象解构

let person = {name:"Jack",age:18};

let {name,age} = person;

// name="Jack",age=18

// 自定义变量名

let {name:username} = person; // username = "Jack"

3. 函数参数解构(高频实用)

function show({name,age}){

console.log(name,age);

}

show({name:"Rose",age:17});

位操作符
按位与 &

规则:对应二进制位同时为 1,结果才是 1;否则 0

按位或 |

规则:对应二进制位有一个为 1,结果就是 1;全 0 才 0

按位异或 ^

规则:对应二进制位相同为 0,不同为 1

一个数异或自身 = 0:a ^ a = 0

一个数异或 0 = 自身:a ^ 0 = a

经典用法:交换两个变量,不用临时变量

let a=2,b=3;

a = a^b;

b = a^b;

a = a^b;

// a=3,b=2

按位取反 ~ (一元运算符)

规则:把 32 位每一位 0 变 1、1 变 0,本质公式:~x = -(x+1)

console.log(~5); //-6

console.log(~0); //-1

console.log(~-3); //2

小技巧:~~num 等价快速取整小数(正负都可用)

~~2.9 //2

~~-2.9 //-2

左移 <<

格式:a << n

规则:二进制整体向左挪 n 位,右侧补 0;等价 a × 2ⁿ

有符号右移 >>

格式:a >> n

规则:二进制整体向右挪 n 位,左侧补符号位(正数补 0,负数补 1);等价除以 2ⁿ,向下取整

无符号右移 >>>(JS 独有特色,C 无完全一样)

格式:a >>> n

规则:不管正负,左侧统一补 0;负数会变成超大正数(因为符号位 1 被替换成 0)

console.log(-1 >>> 0); //4294967295(32位全1转无符号最大值)

console.log(8 >>> 2); //2(正数和>>效果一致)

>>> 无符号右移

C 语言:只有无符号 unsigned 类型才能>>实现无符号右移,signed 负数右移补 1

JS 不分有无符号类型,统一用>>>强制全补 0,负数移位后变巨大正数

速记口诀

与 & 同 1 出 1,或 | 有 1 出 1,异或 ^ 不同出 1;

取反~公式:~x = -(x+1);双波浪快速取整;

左移 <<乘 2,有符号>> 除 2,无符号 >>> 正数同、负数变超大;

C 只允许整数运算,JS 所有值自动转 32 位整数;

常用实用小技巧:

快速取整:~~x、x|0、x>>0

奇偶判断:x & 1

乘除 2 的幂:x<<n等价 ×2ⁿ;x>>n等价 ÷2ⁿ(整数)

不用中间变量交换两数:a^=b;b^=a;a^=b

取相反数:~x +1(补码规则)

条件操作符

是一个三元运算符。

条件 ? 真值结果 : 假值结果

逗号操作符

逗号操作符可以用来在一条语句中执行多个操作:

let num1 = 1, num2 = 2, num3 = 3;

逗号运算符规则:从左到右执行所有表达式,返回最后一个的结果。

let a = (1 + 2, 3 + 4, 5 + 6);

// 分步执行:

// 1. 执行1+2(结果3,丢弃)

// 2. 执行3+4(结果7,丢弃)

// 3. 执行5+6(结果11,作为整体返回值)

console.log(a); // 11

for 循环头部批量更新(最经典用途):

for 循环三段里,用逗号同时更新多个变量

// i从0、j从10;每次i++ 同时 j--

for(let i=0, j=10; i<j; i++, j--){

console.log(i,j);

}

这里 i=0, j=10、i++, j-- 里的逗号就是逗号操作符,批量执行。

指数操作符

符号:**,作用:计算底数的幂次方

公式:a ** b = a的b次方

对比旧写法:等价 Math.pow(a, b)

注意:不能写成 -a ** b

运算优先级:** 高于一元负号 -

-3 ** 2 等价 -(3**2) = -9,不是 (-3)²

想要负数整体做底数必须加括号:(-3)**2

相关推荐
北极星日淘1 小时前
煤炉自动代拍功能开发 | Python 异步任务实现批量下单
开发语言·python·自动化
体验家2 小时前
体验家 XMPlus 网页端问卷 SDK 技术解析:用几行 JavaScript 实现精准场景触发与防打扰机制
开发语言·前端·javascript
VidDown2 小时前
VidDown 工具站:视频分辨率技术
javascript·网络·编辑器·音视频·视频编解码·视频
二十七剑2 小时前
LangGraph 源码深度解析:Node 节点 Protocol 与 StateNodeSpec 核心机制
开发语言·python
AC赳赳老秦2 小时前
OpenClaw + 云数据库运维:自动备份、扩容、迁移 RDS/MySQL 云数据库
运维·开发语言·数据库·人工智能·python·mysql·openclaw
醉城夜风~2 小时前
类和对象III
开发语言·c++
冷小鱼2 小时前
高级研发编码习惯:从规范到艺术,再到AI+时代的人机协同
java·开发语言·python·编码习惯
fox_lht2 小时前
15.4.循环和迭代器的性能比较
开发语言·后端·学习·rust
小鹿软件办公2 小时前
倒计时开启:Chromium 宣布几周内将全面切断 MV2 扩展支持
开发语言·javascript·ublock origin