今天的主角:

Operator Description
一元正值符 " + "(MDN) 一元运算符, 如果操作数在之前不是number,试图将其转换为number

圆括号运算符 " () "(MDN)

圆括号运算符由一对圆括号组成,包裹表达式和子表达式用来覆盖常规的运算符优先级(MDN),达到低优先级的表达式比高优先级的表达式更早运算。

一元正值符 - " + "

? 为什么图例 - 3中 +'1.22' + 1.5 = 2.71999999… ? 查看我的另一篇文章:深入探讨带浮点数运算丢失精度问题(二进制的浮点数存储方式)

首先区分如 let x = '1.20' 是作为变量声明被浏览器解析,包括 function / let / var / const / class 等等这些都是作为 声明语句 被解析。

浏览器预解析到声明语句,则会将其存入堆栈区并为其分配存储空间。

  运算符 - 一元正值符(+)  的作用是 声明语句 --> 表达式语句(“ 使某件事发生 ” 的计算带有副作用的表达式)。

它为什么带有副作用:

除了基本数据类型外,任何数据都会被正值运算符 “ + ” 转换成Number类型数据,包括ObjectArray的引用如

let me = {
name: '97z4moon',
age: '24.00'
} console.log(typeof +me.age, ': ', +me.age)
// number: 24
console.log(typeof +me.name, ': ', +me.name)
// number: NaN

若数据无法被转换成Number类型,则仍然返回number类型的NaN。除此之外,JS特别的 “ Date对象 ” 也是能够被转换成Number类型的数据:

window.onload = function(){
console.log(new Date())
// Wed Apr 07 2021 17:17:12 GMT+0800 (中国标准时间) console.log(new Date().getTime())
// 1617787032426
console.log(+new Date())
// 1617787032426
}

new Date( ) 在正值符作用下等同于 new Date( ).getTime( ) ,发现这一点的我甚至怀疑了 getTime( ) 的存在价值。

小总结

  • 声明语句(MDN):将一条数据、一个函数、一块语句等等声明成一个变量,在堆栈区为其分配内存空间,需要特别注意的是  声明提升(hoisting)
  • 表达式语句(MDN):“ 使某件事发生 ” 的计算带有副作用的语句,需要特别注意的是 运算符的副作用 
  • 运算符(MDN):对单 / 多个数据进行特定规则的运算,有些运算符会包含一些附加作用,如尝试对参与运算数据进行类型转换(Number)的一元正值符 “ + ” ,它们往往会对数据造成意料之外的效果,需要特别注意的是 运算符的优先级

圆括号运算符 - " ( ) "

分组运算符 - 使低优先级比高优先级更早运算。

  1 + 2   * 2     // 5
( 1 + 2 ) * 2 // 6

但我们知道" () " 在JS中还充当其他重要的作用,它们脱离了运算符的概念:

参数传递

funA(12)不是为了优先执行“ 12 ”,它起着另一种至关重要的作用。除此之外它还有其他的作用:

函数调用

funA()

限定作用

条件语句 (Condition)

if (i < 10) { // Some code. }

循环语句 (Loop)

for (var i = 0; i < 10; i++) { // Some code. }

强制表达式运算

我们都知道 ( 1 + 2 ) * 2 能够执行,那么 ( 1 + 2 ) 呢,( 2 ) 呢?

最常用的立即执行函数 Immediately-Invoked Function Expression (IIFE)由此诞生:

图例 -1 和 图例 -2 写法相似,结果相同,但它们绝不相同,浏览器内部发生的事情绝对刺激!

了解立即执行函数的原理,请阅读我的另一篇文章:JS016. 详解匿名函数_立即执行函数_递归函数(自执行函数)

运算符 - 优先级 & 结合性 & 分组短路

运算符有优先级,就如css的权值一样有不同的执行顺序,而一个表达式除了优先级,还有结合性。

我们大多数情况遇到的都是左结合(左到右),如:

2 + 3 * 4    // 2 + 12
1 * 2 ** 3 // 1 * 8

而有些个例是作为右结合被解析的,如赋值运算符:

a = b = 5
// 等价于
a = ( b = 5 )

另一个例子是,只有幂运算符是右结合的,而其他算术运算符都是左结合的。有趣的是,无论结合性和优先级如何,求值顺序总是从左到右

混合求除法和幂:

2 ** 3 / 3 ** 2    //0.8888888888888888...
//等价于
( 2 ** 3 ) / ( 3 ** 2 )

还有一个很常用且很有趣的意外情况:分组与短路

分组( Group )在下表中拥有最高优先级,但并不意味着浏览器总是对分组符号 (...) 内的表达式优先求值,比如涉及到短路时。

短路是条件求值的术语。例如,在表达式  a && ( b + c )  中,如果 a 为虚值(falsy),那么即使 ( b + c ) 在圆括号中,也不会被求值。我们可以说逻辑或运算符(" OR ")是 “短路的”。

除了逻辑或运算符外,其他短路运算符还包括逻辑与(" AND ")、空值合并、可选链和条件(三元)运算符。

a || (b * c);  // 首先对 `a` 求值,如果 `a` 为真值则直接返回 `a` (变量a储存的值)
a && (b < c); // 首先对 `a` 求值,如果 `a` 为虚值则直接返回 `a` (false)
a ?? (b || c); // 首先对 `a` 求值,如果 `a` 不是 `null` 或 `undefined` 则直接返回 `a`
a?.b.c; // 首先对 `a` 求值,如果 `a` 是 `null` 或 `undefined` 则直接返回 `undefined`

3 > 2 && 2 > 1
// 返回 true 3 > 2 > 1
// 返回 false,因为 3 > 2 是 true,然后 true 会在比较运算符中
// 被隐式转换为 1,因此 true > 1 会变为 1 > 1,结果是 false
// 加括号可以更清楚:(3 > 2) > 1

 汇总表

优先级 运算符类型 结合性 运算符
21 分组 n/a(不相关) ( … )
20 成员访问 从左到右 … . …
需计算的成员访问 从左到右 … [ … ]
new(带参数列表) n/a new … ( … )
函数调用 从左到右 … ( … )
可选链(Optional chaining) 从左到右 ?.
19 new(无参数列表) 从右到左 new …
18 后置递增 n/a … ++
后置递减 … --
17 逻辑非 (!) 从右到左 ! …
按位非 (~) ~ …
一元加法 (+) + …
一元减法 (-) - …
前置递增 ++ …
前置递减 -- …
typeof typeof …
void void …
delete delete …
await await …
16 幂 (**) 从右到左 … ** …
15 乘法 (*) 从左到右 … * …
除法 (/) … / …
取余 (%) … % …
14 加法 (+) 从左到右 … + …
减法 (-) … - …
13 按位左移 (<<) 从左到右 … << …
按位右移 (>>) … >> …
无符号右移 (>>>) … >>> …
12 小于 (<) 从左到右 … < …
小于等于 (<=) … <= …
大于 (>) … > …
大于等于 (>=) … >= …
in … in …
instanceof … instanceof …
11 相等 (==) 从左到右 … == …
不相等 (!=) … != …
一致/严格相等 (===) … === …
不一致/严格不相等 (!==) … !== …
10 按位与 (&) 从左到右 … & …
9 按位异或 (^) 从左到右 … ^ …
8 按位或 (|) 从左到右 … | …
7 逻辑与 (&&) 从左到右 … && …
6 逻辑或 (||) 从左到右 … || …
5 空值合并 (??) 从左到右 … ?? …
4 条件(三元)运算符 从右到左 … ? … : …
3 赋值 从右到左 … = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
2 yield 从右到左 yield …
yield* yield* …
1 逗号 / 序列 从左到右 … , …

- END -

JS006. 详解自执行函数原理与数据类型的快速转换 (声明语句、表达式、运算符剖析)的更多相关文章

  1. javascript模块化编程-详解立即执行函数表达式IIFE

    一.IIFE解释 全拼Imdiately Invoked Function Expression,立即执行的函数表达式.  像如下的代码所示,就是一个匿名立即执行函数: (function(windo ...

  2. 详解立即执行函数(function(){}()),(function(){})()

    要知道这几种写法之间的区别,我们要先聊些题外话——js中函数的两种命名方式,即表达式和声明式. 函数的声明式写法为:function foo(){/*...*/},这种写法会导致函数提升,所有func ...

  3. [转帖]万字详解Oracle架构、原理、进程,学会世间再无复杂架构

    万字详解Oracle架构.原理.进程,学会世间再无复杂架构 http://www.itpub.net/2019/04/24/1694/ 里面的图特别好 数据和云 2019-04-24 09:11:59 ...

  4. 淘宝JAVA中间件Diamond详解(2)-原理介绍

    淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...

  5. SpringCloud 详解配置刷新的原理 使用jasypt自动加解密后 无法使用 springcloud 中的自动刷新/refresh功能

    之所以会查找这篇文章,是因为要解决这样一个问题: 当我使用了jasypt进行配置文件加解密后,如果再使用refresh 去刷新配置,则自动加解密会失效. 原因分析:刷新不是我之前想象的直接调用conf ...

  6. ggplot2作图详解:入门函数qplot

    ggplot2作图详解:入门函数qplot   ggplot2的功能不用我们做广告,因为它的作者Hadley Wickham就说ggplot2是一个强大的作图工具,它可以让你不受现有图形类型的限制,创 ...

  7. [转帖]详解Linux系统inode原理--硬链接、软链接、innodb大小和划分等

    详解Linux系统inode原理--硬链接.软链接.innodb大小和划分等 原创 波波说运维 2019-07-17 00:03:00 https://www.toutiao.com/i6713116 ...

  8. RocketMQ详解(一)原理概览

    专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...

  9. jQuery的deferred对象详解 jquery回调函数

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html jQuery的 ...

随机推荐

  1. canal同步异常:当表结构变化时,同步失败

    场景 canal 同步Mysql一段时间后突然失败,报如如下错误: 2021-08-06 16:16:51.732 [MultiStageCoprocessor-Parser-Twt_instance ...

  2. POJ 1190 生日蛋糕题解

    题目地址:http://poj.org/problem?id=1190 一道很有趣的搜索题--主要是剪枝-- 我弄了5个剪枝: 1.当前剩余层数>=上层半径,剪掉 2.当前剩余层数>=上层 ...

  3. Java互联网架构师系统进阶课程 (一)【享学】

    2.线程的并发工具类 Fork-Join 什么是分而治之? 规模为N的问题,N<阈值,直接解决,N>阈值,将N分解为K个小规模子问题,子问题互相对立,与原问题形式相同,将子问题的解合并得到 ...

  4. 离线webpack创建vue 项目

    参考地址: https://blog.csdn.net/feinifi/article/details/104578546 画重点: // 需要带上参数--offline表示离线初始化. --offl ...

  5. 来看看是什么原因导致生产服上的系统CPU高的?

    我们可能会遇到生产服务器CPU很高的问题,有时候能确定是哪个进程,但是不知道这个进程都在干什么,所以也无从下手,无法解决问题.只能不断的重启,重启等. 最近也看了[一线码农]的一些教程,觉得都很不错, ...

  6. appium自动化测试(5)-一些pyhon操作

    1.套件的问题 将所有的测试用例加进去,会一个个执行,用于用例名字没有规范test开头的时候 def suite(): suite = unittest.TestSuite suite.addTest ...

  7. 基于AOP和HashMap原理学习,开发Mysql分库分表路由组件!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 什么?Java 面试就像造火箭 单纯了! 以前我也一直想 Java 面试就好好面试呗 ...

  8. STM32—TIMx输出PWM信号驱动MG996R舵机

    文章目录 一.前言 二.MG996R舵机简介 三.TIM定时器简介 四.通用定时器TIMx 1.TIMx主要功能 2.TIMx框图 3.计数单元 4.时钟选择 5.输出比较PWM 五.TIM3输出双路 ...

  9. Kurento实战之四:应用开发指南

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. VS+Qt+Halcon——显示图片,实现鼠标缩放、移动图片

    摘要 本篇博文记录一下,用VS+Qt+Halcon实现对图片的读取以及鼠标缩放,移动(鼠标事件调用了halcon自带的算子)的过程.以及遇到的坑..... 先来看一下动态效果图: 主要控件: 添加一个 ...