JS中的一元操作符
- 表达式
- 一元操作符
- 优先级
- 结合性
- 运算顺序
表达式是什么?
就是JS 中的一个短语,解释器遇到这个短语以后会把对它进行计算,得到一个结果参与运算,我们把这种要参与到运算中的各种各样的短语称为表达式。实际上,JS 的代码就是由表达式和操作符构成的,可以说除了操作符以外的基本都是表达式。
例如:a + 1;这行代码中,加号左边的a和右边的1都是表达式,而加号是操作符。
表达式的分类(大概可以分成6类)
1, 原始表达式(4种):常量、变量、直接量、关键字
- 常量:那些不会改变的量。其实在JS中大部分东西都是可以改变的,如果我们想要让一个东西保持不变,例如关于圆的计算中的PI,可以把它设成常量;常量通常会使用大写字母,或者用下划线来表示;
const PI = 3.14;
PI = 3; // 修改常量的值会报错 - 变量:可以随时发生变化;(这个与JS的基础数据类型不可变不是一码事)
var a = 1;
a = 2; // 给变量a重新赋值 - 直接量:数字、字符串、正则表达式;如:1 + 1; 这里1就是一个直接量;
- 关键字:所有关键字都是表达式;
2, 初始化表达式:
- var obj = {name: ‘suki};
- var arr = [1, 2, 3];
3, 函数定义表达式: function foo() {}
4, 函数调用表达式:foo();
5, 属性访问表达式:obj.name; obj[name];
6, 对象创建表达式: new Foo();
一元操作符
只可以操作一个表达式的符号,共有9个;
一元加
- 对数字进行一元加操作,结果返回数字本身,要注意对负数进行一元加操作结果还是负数啦,不要以为会得到整数;
- 对布尔类型进行一元加操作,true的话返回1,false返回0;
- 对null进行一元加操作,返0;
- 对undefined进行一元加操作,返回NaN;
- 对字符串进行一元加操作,有两种结果,如果字符串由纯数字构成的话,返回1,如果不是则返回NaN;
- 对对象进行一元加操作,也有两种结果,一是返回数字,二是返回NaN;操作过程中首先会调用valueOf方法,如果得不到数字结果,就调用toString方法,再对得到的字符串进行一元加操作;
用途:将表达式转换成数字;
一元减
- 对数字使用:返回数字的负数;
- 对其他数据类型使用:首先尝试把表达式转换成数字,再取负数;
var b = false;
-b; // -0
首先将false转换成数字得到0,然后取0的负数得到-0,在 JS 中 +0 === -0; // true;
前置递增、递减操作符
解释器首先会对表达式进行加一或减一的操作,然后再让表达式参与到后面的运算中;
var num1 = 2;
var num2 = 20;
--num 1 + num2; // 1 + 20
后置递增、递减操作符
先让表达式参与运算,再对表达式进行加一或减一的操作;平常后置递增、递减操作符用得比较多一点;
var num1 = 2;
var num2 = 20;
num 1-- + num2; // 2 + 20
num1; //
var age = 21;
++age; //
// 如果操作数是数字的话,这两者写法是一样的
age = age + 1; //
但如果涉及到字符串表达式,情况就不一样了
var name = ‘suki’;
++name; // NaN
// 只要有一个操作数是字符串,加号就会变成字符串连接符
name = name + 1; // ‘suki1’
优先级
就像在数学表达式里,先算乘除再算加减, 因为乘除的优先级比加减高;
属性访问 > 一元操作符 > 乘除 > 加减 > 比较 > 相等 > 与运算 > 或运算 > 三目运算 > 赋值运算
不用记那么多,只要记住下面三点就好了:
- 属性访问表达式拥有最高优先级;
- 赋值运算(=)具有最低优先级(其实比等号更低的是逗号,但平常逗号不会参与到运算中);
- 在所有运算符中,一元运算符拥有最高优先级;
var a = 3;
++a == 3; // false;
因为相等(==)的优先级比递增操作符(一元操作符)要低,所以会先计算++a,得到4,再计算4==3,返回false;
结合性
当一行代码中存在多个运算符,而且这些运算符的优先级相等时,那要怎么计算?这就引出了结合性的问题了;
- 左结合
- 右结合
其实就是从左边开始算还是从右边开始算的问题;
所有一元操作符、三目运算符和赋值运算符都是右结合,其他的操作符都是左结合;
!a++;
如果是从左往右运算,!a先得到一个布尔类型,(!a)++最后得到一个数字类型;
如果是从右往左运算,a++先得到一个数字类型,!(a++)后得到一个布尔类型;
逻辑非(!)和递增操作符(++)都是一元运算符,当两个一元运算符同时存在于一行代码中时,从右往左运算,所以最后会得到一个布尔类型的结果;
x = a ? b : c ? d : e ? f : g;
三目运算符也是右结合的,从右向左运算,相当于
x = a ? b : (c ? d : (e ? f : g));
var a = b = c = d;
连等赋值,也是从右向左运算,先取d的值,把它赋给c,再把c的值赋给b,再把b的值赋给a;
运算顺序
当表达式里还包含表达式时怎么处理?
a = 1;
b = a +++ a;
console.log(a, b); // 2 3
这种情况JS永远是从左向右运行;
- 首先JS会先计算b,得到b;
- 再计算a++,得到结果1,但是这个过程结束后a的值变成了2;
- 第三步计算后面的a,得到2;
- 第四步计算1+2,得到3;
- 把3赋值给b;
var a = 1;
b = a ++ + ++ a; //
- 先算a++,得到1,这时a的值变成了2;
- 再算++a,得到3;
- 1+3得到4;
- 把4赋值给b;
一元加、一元减、递增操作符、递减操作符
这四个操作符对所有数据类型都有效;
- 一元加、一元减其实就是将任何数据类型转换成数字类型(因为所有数据类型都可以被转换成数字);
- 递增操作符、递减操作符把任何数据类型先转换成数字,然后再进行加一或减一的操作;
但对小数进行递减操作的时候得到的结果可能会与想象中的不一样
var a = 1.1;
--a; // 0.10000000000000009
所以一定要先把小数转换成整数再计算,得到结果再转换回小数;
按位非
只需知道一点,对一个数字进行按位非运算,就是取负值再减一;例如对10进行按位非运算得到结果是-11;
按位与
可以用来判断数字的奇偶性;
function even_or_odd(number) {
return (number & 1) ? "Odd" : "Even";
}
- 奇数转换成二进制最后一位是1,所以和1进行按位与运算会返回1;
- 偶数转换成二进制最后一位是0,所以和1进行按位与运算会返回0;
逻辑非
把任何数据类型转换成布尔类型,再取反;
字符形式的一元操作符
typeof: 可以用括号把它要操作的表达式括起来,但不要误以为它是函数,括号只是方便让人看出运算逻辑而已;
void: 无论表达式是什么,都是返回一个undefined;
delete: 用于删除对象的属性;
字符形式的二元操作符
instanceof: 用来判断对象的构造函数,但用得不多;
in: 用来遍历对象;
————整理自沙翼老师的前端音频教程#陪你读书#(喜马拉雅)
JS中的一元操作符的更多相关文章
- js中的new操作符与Object.create()的作用与区别
js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...
- JS中的new操作符
在JS中定义一个构造函数,然后用new操作符构造对象obj,JS代码如下. function Base(){ this.name = "swf"; this.age =20; } ...
- js中的一元加法和一元减法
大多数人都熟悉一元加法和一元减法,它们在 ECMAScript 中的用法与您高中数学中学到的用法相同. 一元加法本质上对数字无任何影响: var iNum = 20; iNum = +iNum; al ...
- JS中的 new 操作符简单理解
首先上一一个简单的 new 操作符实例 var Person = function(name){ this.name = name; this.say = function(){ return &qu ...
- javascript中的一元操作符
题目如下: var s1 = "01"; var s2 = "1.1"; var s3 = "z"; var b = false; var ...
- JS中的delete操作符
首先,delete删除成功返回true,失败返回false. js代码: function wxCount ($element) { this.init($element); } wxCount.pr ...
- JS 中的 new 操作符
按照javascript语言精粹中所说,如果在一个函数前面带上new来调用该函数,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将被绑定到那个新对象上.这个话很抽象,我想 ...
- js中的new操作符解析
new 操作符做了以下事情: 1.创建一个对象,将对象赋值给this function Person(name, age) { console.log(this) //Person {} } let ...
- JS中void(0)操作符的使用
今天 在看源码时,发现这种写法 if(value === void(0)){ // } 以前没有见过这种写法,感觉就是判断一个变量是否有值,官网上是这样说的: void运算符 对给定的表达式进行求值, ...
随机推荐
- 第 8 章 容器网络 - 072 - 一文搞懂各种 Docker 网络
Docker 起初只提供了简单的 single-host 网络,显然这不利于 Docker 构建容器集群并通过 scale-out 方式横向扩展到多个主机上. 跨主机网络方案: Docker Over ...
- @RequestMapping的Ant风格URL
Ant风格资源地址支持3中匹配符 ? 匹配文件名中一个字符. * 匹配 文件名中任意字符 ** 匹配多层路径 例如 /hello/*/myspring 匹配 /hello/abc/mysprin ...
- unity项目build成webgl时选择生成目录(解决方法)
在unity里点击File>>Build Settings...>>勾选你要生成的Scenes>>选择webgl>>后面Development Buil ...
- java 获取微信公众号code为空
失败的原因是没将回调方法encode转换 /** * URL编码(utf-8) * * @param source * @return */ public static String urlEncod ...
- numpy 数组索引数组
在numpy中,数组除了可以被整数索引,还可以被数组索引. a[b]就是已数组b的元素为索引,读取数组a的值. 当被索引数组a是一维数组,b是一维或则多维数组时,结果维度维度与索引数组b相同. a = ...
- 思科模拟器PacketTracer7--利用一台交换机将两台pc划分到不同vlan下
实验2—3 实验内容:将同一交换机下的两台pc划分到不同vlan中 实验工具:思科模拟器PacketTracer7 使用设备:一台交换机,两台PC 实验步骤: 一.配置网络拓扑图 注:1.连线可选择闪 ...
- ORA-28000 帐户已被锁定问题处理
1.问题描述 应用监控程序报警ORA-28000,PL/SQL无法登陆数据库 2.问题分析 oracle11g中默认在default概要文件中设置了 “FAILED_LOGIN_ATTEMPTS=10 ...
- vue-cli脚手架build目录中的webpack.prod.conf.js配置文件
// 下面是引入nodejs的路径模块 var path = require('path') // 下面是utils工具配置文件,主要用来处理css类文件的loader var utils = req ...
- js 快速生成数组的方法
//实现方法一:循环赋值var arr1 = new Array(100);for(var i=0;i<arr1.length;i++){ arr1[i] = i;}console.log(ar ...
- 使用 ZipArchive 生成Zip文件备注
近两日研究了Abp.io 中模板项目的生成原理,是从Github下载源码包,进行修改.替换,然后生成新的zip包提供下载. 项目内部使用了 这个包 Ionic.Zip Version=" ...