摘要:是中最简单的操作符。在变量前使用一元减操作符遵循一元加操作符规则,最后将得到的数值转换为负数。位操作符位操作符是按内存中表示数值的位来操作数值。位操作符就是先将位的值转换成位的整数,然后执行操作,再将结果转换为位。位操作符对和当做来处理。
一元操作符
只能操作一个值的操作符叫做一元操作符。是ECMAScript中最简单的操作符。
递增和递减操作符执行前置递增递减操作时,变量的值是在语句被求值之前改变的。(在计算机科学领域,这种情况通常被称为副效应).
执行后置递增递减操作时,变量的值是在语句被求值之后改变的。
当一条语句只有递增或递减操作时,前置和后置没有区别。
let num1 = 1; ++num1; console.log(num1); // 2 let num2 = 1; num2++; console.log(num1); // 2 let num3 = 1; console.log(++num3); // 2 let num4 = 1; console.log(num4++); // 1 let num5 = 2; let num6 = 20; let num7 = --num5 + num6; // 21 let num8 = num5 + num6; // 21 上面的语句改变了num5的值 let num9 = 2; let num10 = 20; let num11 = num9-- + num10; // 22 let num12 = num9 + num10; // 21 上面的语句改变了num5的值
除了适用于整数,还有可以用于字符串、布尔值、浮点数值、对象。最终都变为数值变量。
String:包含有效数字字符则先转为数值,再执行加减1;不包含有效数字字符则将变量值设置为NaN。
Boolean:将 true(false) 转为 1(0),再执行加减1。
Object: 先调用 valueOf() 获得一个可供操作的值,然后对该值应用前述规则。如果结果是NaN,则调用 toString() 后再应用前述规则。
let s1 = "2", s2 = "str"; let b1 = true, b2 = false; let f = 1.1; let o1 = { valueOf() { return 10; } } let o2 = { valueOf() { return NaN; } } console.log(++s1); // 3 console.log(++s2); // NaN console.log(++b1); // 2 console.log(++b2); // 1 console.log(--f); // 0.10000000000000009 (由于浮点舍入错误所致) console.log(--o1); // 9 console.log(--o2); // NaN一元加和减操作符 在变量前使用一元加操作符:
Number: 不变
String:包含有效数字字符则先转为数值;不包含有效数字字符则将变量值设置为NaN。
Boolean:将 true(false) 转为 1(0)。
Object: 先调用 valueOf() 和(或)toString() 方法,再转换得到的值。
let n = 1; let s1 = "10", s2 = "10a", s3 = "a10", s4 = "a"; let b1 = true, b2 = false; let f = 1.1; let o1 = { valueOf(){ return 10; } }, o2 = { valueOf(){ return NaN; } } console.log(+n); // 1 console.log(+s1); // 10 console.log(+s2); // NaN console.log(+s3); // NaN console.log(+s4); // NaN console.log(+b1); // 1 console.log(+b2); // 0 console.log(+f); // 1.1 console.log(+o1); // 10 console.log(+o2); // NaN在变量前使用一元减操作符:
遵循一元加操作符规则,最后将得到的数值转换为负数。
位操作符位操作符是按内存中表示数值的位来操作数值。速度快。
位操作符就是先将64位的值转换成32位的整数,然后执行操作,再将结果转换为64位。ECMAScript中的数值都是以IEEE-754 64位格式存储。
位操作符对 NaN 和 Infinity 当做 0 来处理。
对于非数值,会先使用 Number() 函数将该值转换为一个数值(自动完后),再执行操作,最终得到一个数值。
在处理有符号的整数时,是不能访问位31的。
对于有符号的整数,32位中的前31位用于表示整数的值。第32位用于表示数值的符号:0表示整数,1表示负数。这个表示符号的位叫做符号位,它的值决定了其他位数值的格式。默认情况下,ECMAScript 中的所有整数都是有符号整数,不过也存在无符号整数。对于无符号整数,第32位不再表示符号,那么它能表示的值自然可以更大。
正数以纯二进制格式存储:
例如数值18的二进制:00000000000000000000000000010010
负数以二进制补码的格式存储:
二进制补码计算方式:
求这个数值绝对值的二进制码。
求二进制反码。0替换为1,1替换为0。
得到的二进制反码加1。
获取 -18 的二进制码:
首先求得 18 的二进制码即:
0000 0000 0000 0000 0000 0000 0001 0010
求二进制反码:
1111 1111 1111 1111 1111 1111 1110 1101
将二进制反码加1:
1111 1111 1111 1111 1111 1111 1110 1110
ECMAScript会尽力向我们隐藏所有上面的这些操作,以更合乎逻辑的形式展现出来:
const num = -18; num.toString(2); // "-10010"按位非(NOT)
由符号 ~ 表示,返回数值的反码。本质就是操作数的负值减1。
const n1 = 25; // 二进制 00000000000000000000000000011001 const n2 = ~n1; // 二进制 11111111111111111111111111100110 console.log(n2); // -26 这里也解释了为什么计算二进制补码的第3步要加1。按位与(AND)
由符号 & 表示。两个数值对应位都是1才返回1,否则返回0。
const result = 25 & 3; console.log(result); // 1 // 二进制: // 25 = 00000000000000000000000000011001 // 3 = 00000000000000000000000000000011 // AND = 00000000000000000000000000000001按位或(OR)
由符号 | 表示。两个数值对应位有一个1就返回1,否则返回0。
const result = 25 | 3; console.log(result); // 27 // 二进制: // 25 = 00000000000000000000000000011001 // 3 = 00000000000000000000000000000011 // OR = 00000000000000000000000000011011按位异或(XOR)
由符号 ^ 表示。两个数值对应位只有一个1才返回1,否则返回0。
const result = 25 ^ 3; console.log(result); // 26 // 二进制: // 25 = 00000000000000000000000000011001 // 3 = 00000000000000000000000000000011 // OR = 00000000000000000000000000011010左移
由符号 << 表示。将数值的所有位向左移动指定位数。
左移不会影响操作数的符号位。例如:将 -2 向左移动 5 位,结果将是 -64 ,而非 64。
const result = 2 << 5; console.log(result); // 64 // 二进制: // 2 = 00000000000000000000000000000010 // result = 00000000000000000000000001000000有符号的右移
由符号 >> 表示。将数值的向右移动指定位数,保留符号位,并且用符号位的值来填充空位。
有符号的右移与左移恰好相反。例如:将 64 向右移动 5 位,结果将是 2。
const result = 64 >> 5; console.log(result); // 2 // 二进制: // 64 = 00000000000000000000000001000000 // result = 00000000000000000000000000000010无符号的右移
由符号 >>> 表示。将数值的所有位向右移动指定位数,不 保留符号位,并且使用 0 来填充空位。
对于正数来说,无符号右移与有符号右移没区别。对于负数来说:首先空位是由 0 来填充,而不是符号位的值;其次,会把负数的二进制码(是正数二进制码的反码加1)当成正数的二进制码,也就会导致结果非常之大。
const result1 = 64 >>> 5; console.log(result1); // 2 // 二进制: // 64 = 00000000000000000000000001000000 // result1 = 00000000000000000000000000000010 const result2 = -64 >>> 5; console.log(result2); // 134217726 // 二进制: // -64 = 11111111111111111111111111000000 // result2 = 00000111111111111111111111111110参考
《JavaScript高级程序设计》(第三版)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105033.html
摘要:函数式编程前端掘金引言面向对象编程一直以来都是中的主导范式。函数式编程是一种强调减少对程序外部状态产生改变的方式。 JavaScript 函数式编程 - 前端 - 掘金引言 面向对象编程一直以来都是JavaScript中的主导范式。JavaScript作为一门多范式编程语言,然而,近几年,函数式编程越来越多得受到开发者的青睐。函数式编程是一种强调减少对程序外部状态产生改变的方式。因此,...
摘要:基础巩固基础总结使用已经好几年了,由于工作主要是做服务端开发,在工作中逐渐发现的使用范围原来越广泛。这里要注意,务必将基础部分掌握牢靠,磨刀不误砍柴功,只有将基础部分掌握并建立起系统的知识体系,在后面学习衍生的其他模式才能游刃有余。 基础巩固:JavaScript基础总结 使用JavaScript已经好几年了,由于工作主要是做服务端开发,在工作中逐渐发现JavaScript的使用范围原...
摘要:在上百种语言中算是命好的一个,还有就是最近纳入高考体系的。由以下三个部分构成。就是对实现该标准规定的各个方面内容的语言的描述。是针对但经过扩展的用于的应用程序编程接口。将页面映射为由节点构成的树状结构。 JavaScript的历史这里就不再赘述了,当然JavaScript的历史还是比较有意思的。在上百种语言中JavaScript算是‘命’好的一个,还有就是最近纳入高考体系的python...
摘要:引子前不久我建立的技术群里一位问了一个这样的问题,她贴出的代码如下所示执行结果如下所示第一个第二个这是一个令人诧异的结果,为什么第一个弹出框显示的是,而不是呢这种疑惑的原理我描述如下一个页面里直接定义在标签下的变量是全局变量即属于对象的变量 1) 引子 前不久我建立的技术群里一位MM问了一个这样的问题,她贴出的代码如下所示: var a = 1; function hehe...
摘要:中的一切都可以视为对象,除了两个特例和。上例中的第三个情形已说明删除对象的属性删除属性的唯一方法是使用,将属性值设置为或只是移除了与属性相关的值,并没有真正删除属性本身。命名对象的属性对象的属性可以用普通字符或字符串来命名。 Javascript 中的一切都可以视为对象,除了两个特例:null 和 undefined。 false.toString(); // false [1, 2...
摘要:但事实上,位操作符并不是这么认为的。再者,在中使用位操作符的地方毕竟太少,如果你执意使用位操作符,未来维护这段代码的人又对中的位操作符的坑不熟悉,这也会造成不利的影响。所以,我对大家的建议是,尽量在中别使用位操作符。 本文最早在我的个人博客《咀嚼之味》发布:http://jerryzou.com 如果你的第一门编程语言不是 JavaScript,而是 C++ 或 Java,那...
阅读 3553·2021-11-12 10:36
阅读 3808·2021-09-22 15:48
阅读 3525·2019-08-30 15:54
阅读 2550·2019-08-29 16:44
阅读 2346·2019-08-29 16:08
阅读 2381·2019-08-29 16:06
阅读 1255·2019-08-29 15:21
阅读 3155·2019-08-29 12:39