属性访问表达式
- 第一种写法是表达式后面跟随一个句点和标识符,第二种写法是使用中括号,中括号内是另外一种表达式;
在‘.’和‘[’之前的表达式总是优先计算; - null和undefined不包含任何属性;
- 如果使用中括号,js就会计算中括号内的表达式的值,并将其转换成为字符串;
- ‘.’方法只是用于属性名是合法的标识符,并且知道要访问的属性的名字(也就是说要是一个固定的值);
- 如果属性名称是一个保留字、含有空格和标点符号或者数字的,那就要使用中括号的写法;当属性名是通过计算得出的值而不是一个固定得知的时候,这事就必须使用中括号写法;
运算符描述
注意:运算符包含隐式的类型转换,例如
"3"+"5" =>15
“+”选择符优先考虑字符串的连接,如果两个操作数都不是类字符串的,那么将进行算术加法运算。另外需要注意的是加号运算符和字符串与数字在一起使用的时候,需要考虑的是结合性
1 + 2 + " hello" =>"3 hello"
1 + (2 + " hello") =>"12 hello"
位运算符有&、|、^(异或)、~(非)、<<、>>、>>>(无符号右移);
关系表达式
=、==、===的区分
分别为赋值,相等,全等;
!=与==比较结果相反,!==与===比较结果相反;
对象和它本身相等,但是和任何其他对象都不相等,即使属性属性值等全部一样;
- ===
如果两个操作数都是null或者undefined,则他们的值不相等;
如果其中一个值是NaN,或者两个值都是NaN,则它们不相等;
0与-0相等; - ==
如果一个值是null,另一个是undefined,那么他们相等
如果一个值是字符串,另一个值是数字,那么先将字符串转换成数字,然后进行比较
如果操作数是布尔值,那么先将他们转换成01之后在进行比较
比较运算符
关于比较运算符,需要注意的是
- 如果两个操作数是字符串,那么将按照字母表的顺序进行比较
- 当在对象转换成为原始值之后,如果至少有一个操作数不是字符串,那么两个操作数都将转换成为数字进行比较
- 字符串的标识区分大小写的,所有的大写字母都小于所有的小写字母
- Infinity比所有的数字都大,-Infinity比所有的数字都小
- 加号运算符和比较运算符有所不同,差别就是前者更偏向于字符串,后者更偏向于数字,比较运算符只有在两个操作数都是字符串的情况下才会进行字符串的比较。
- <=在判断相等的时候并不依赖于相等运算符或者是全等运算符,而是简单的不大于,>=同理.
1 + 2; //3
"1" + "2"; //12
"1" + 2; //12
11 < 3; //false
"11" < "3" //true
"11" < 3 //false
in运算符
左操作数是一个字符串或者是能转换成字符串的值,右操作数是一个对象,只有这个对象中包含名为左边操作数的属性名的时候,表达式才会返回true,否则返回false,注意,这里是属性,不是属性值。
instanceof 运算符
左操作数是对象右操作数是对象的类,如果左边的操作数是右边类的实例,就返回true。否则返回false。
逻辑表达式
假值有:false、null、undefined、0、-0、NaN、“”(空字符串)
- 与(&&) 是短路逻辑运算符(尽量避免计算右操作数);
if(a==b) stop(); //等同于
(a==b) && stop();
- 或(||)也是短路逻辑运算符;
var w = w || window; //在使用函数传参的时候常常使用这样的表达式解决没有接收到参数就使用默认值的情况
- 非(!)一元运算符,取反,具有最高优先级
表达式的计算
JavaScript可以运行由源代码组成的字符串,并产生一个值。通过全局函数eval()来完成这个操作。
注意,eval()是一个函数,所以可以赋值给其他变量
var f = eval;
f(2+3); //5
eval()只有一个参数,执行步骤如下:
- 传入的参数不是字符串,直接返回这个参数;
- 是字符串,对字符串进行编译,如果编译不成功,报错;
- 编译成功,执行代码,返回字符串中最后一个表达式或语句的值,如果没有值,就返回undefined。
其他运算符
条件运算符(JavaScript中唯一的三元运算符)
?:表示,将第一个操作数作为布尔值表示,若为真,计算第二个操作数,并返回计算结果,否则计算第三个操作数,返回计算结果。
x > 0 ? x : -x;
//求取绝对值
typeof运算符
delete运算符
delete是一元运算符,用来删除元素。我们来看一个例子
var arr = [0,1,2,3,4];
delete arr[1];
console.log(arr);
从输出结果中可以看出,数组的长度并没有发生改变,被删除的属性的位置是undefined,就仿佛删除之后留下了一个空洞。当删除这个属性之后,这个属性就不再存在,所以读取一个不存在的属性就会返回undefined,我们可以通过使用in操作符进行判断属否存在该属性。
delete希望操作数是一个左值,如果它不是左值,那么delete就不进行任何操作并返回true,否则,delete会删除这个指定的值。注意!一些内置核心和客户端属性是不能删除的,用户通过var语句声明的,function定义的函数,以及函数参数都是不能删除的。
var a = 1;
console.log(delete a);
//false
var o = {x:1,y:2};
delete o.x; //删除,返回true
typeof o.x; //undefined
delete o.x; //删除不存在的值,返回false
delete o; //返回false
delete 1; //返回true,但不执行任何操作
this.x = 1; //定义全局属性
delete this.x; //删除成功,返回true
x; //报错,x is not defined
延伸
什么是左值右值呢?
一句话,能够获取该值的地址就是左值,否则就是右值。比如我们var s = 1; 在这里,s就是左值,因为我们可以通过&s获取s的地址,delete 1中的1就是右值,因为它获取不到地址。
逗号运算符
二元运算符,它的操作数可以是任意类型,表达式结果返回最后一个表达式的运算结果,但是会计算左边的表达式,只是会忽略掉表达式结果,返回最后一个结果。
i=1,j=2,k=3; //3