今天的主角:

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. C++//菱形继承 //俩个派生类继承同一个基类 //又有某个类同时继承俩个派生类 //成为 菱形继承 或者 钻石 继承//+解决

    1 //菱形继承 2 //俩个派生类继承同一个基类 3 //又有某个类同时继承俩个派生类 4 //成为 菱形继承 或者 钻石 继承 5 6 #include <iostream> 7 #i ...

  2. C++//递增运算符重载

    1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 //重载递增运算符 6 7 //自定义 ...

  3. 面试利器!字节跳动2021年Android程序员面试指导小册已开源

    整份手册分为两个部分,分别是:Java部分.Android部分.数据结构与算法篇.字节跳动2020年全年面试题总结篇! 每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多,这里就截取一部分图 ...

  4. 掌握JavaScript中的Promise,实现异步编程

    事件循环 基本介绍 JavaScript是一门单线程的编程语言,所以没有真正意义上的并行特性. 为了协调事件处理.页面交互.脚本调用.UI渲染.网络请求等行为对主线程造成的影响,事件循环(event ...

  5. 【javaFX学习】(二) 面板手册

    移至http://blog.csdn.net/qq_37837828/article/details/78732591 更新 找了好几个资料,没找到自己想要的,自己整理下吧,方便以后用的时候挑选,边学 ...

  6. 关于Feign、Jackson、RabbitMQ、Jrebel插件的开发中遇到的问题

    在工作实际开发中需要开发一个消息模块对外提供统一的接口feign调用提供消息加载到MQ队列的服务,采用泛型的形式. 刚开始搭建好之后,正好需要做一个全局的日志添加到zuul网关中,通过网关feign ...

  7. Spring全家桶--单数据源的配置

    前言 spring数据源的配置网络上有很多例子,这里我也来介绍一下单数据源配置的例子,基于SpringBoot的方式和原生的Spring的方式. 一.生成项目骨架(SpringBoot),运行一个简单 ...

  8. asp.net mvc 传值

    视图的查找 asp.net MVC 不需要用using 释放资源

  9. [C#]c#中数据的同步加锁机制 的几种方法

    一,锁定机制最简单的做法就是使用锁定关键字Lock.Lock关键字英文中就是锁的意思,顾名思义就是为操作加上一把锁.它的语法如下: lock(lockObj){//加锁的代码段,一般是操作共同资源的代 ...

  10. vsftpd - FTP 服务器安装

    由于要将本地程序上传至云服务器中,所以需要给云服务器端安装ftp服务器.记录一下ftp的安装过程,以便以后使用.服务器端所用系统为Ubuntu16.04. 1. 安装ftp服务器, apt-get i ...