一、JavaScript表达式
1、主要表达式:不能细分成更小的表达式,是构成其他复杂表达式的组成部分。
包括:常量或字面量,某些语言关键字,变量引用。
常量或字面量:12.3,/pattern/,"abc"
关键字:null,true,false,this
变量引用:i,sum,undefined(不是关键字,是个全局变量)
2、对象或者数组初始化器是一个表达式,如:{x:1,y:2};[1,2,3]
3、函数定义也是一个表达式,如:var func=function(x){return x*x;}
4、属性访问表达式,两种方式:expression.identifier或者expression[expression]。如:
var obj={x:1,y:{z:2}};var arr=[obj,4,[5,6]];
obj.y.z// =>2 obj["x"]//=>1 arr[2]["1"]//=>6 arr[0].x//=>1
5、调用表达式(包括调用函数和方法),如:fun(),Math.sqrt(4),arr.sort()
6、对象创建表达式:(调用构造函数),如new Object(),new Point(2,3);
7、
二、JavaScript操作符:
分类:算术操作符,逻辑操作符,关系操作符,赋值操作符。按操作数可分为一元,二元,三元操作符。
一元:+,-,!,~,++,--,typeof,delete,void
二元:+,-,*,/,%,<<,>>,>>>,>,>=,<,<=,instanceof,in,==,!=,===,!==,&,|,^,&&,||,=,+=,*=,/=,%=,>>=,>>>=,<<=,&=,|=,^=,最后有逗号运算符:,
三元:?:
操作符具有优先级和结合性,这两者会影响一个复杂表达式的求值顺序。
二元算术操作符:
包括,+,-,*,/,%,其中除+外,其他四个比较简单,就是把操作数转成数值,然后运算,如果有一个操作数为NaN,结果就为NaN。
/比较特别,因为JavaScript数值都是浮点型,所以两个整型相除,结果不会像其他语言一样取整,可能存在余数。如5/2在JavaScript中结果为2.5,在java和c++中为2
%同样比较特别,因为两个浮点型,也可以取余数,比如6.5%2.1结果为0.2
+可以把两个数值相加,也可以把两个字符串相连。如果两个操作数,有一个为字符型,+执行的是字符串的相连。如果两个操作数都是数值型,+执行的是数值的相加。
如果两个操作数都不是数值型,也没有任何一个为字符型,这个时候会必须进行格式转换,但是是都转换成数值型,还是字符串型,需要根据情况判断,+遵循以下规则:
1、如果任何一个操作数为object类型,把object转成primitive类型(转换规则之前讲过),Date型优先使用toString()转换,其他对象如果valueOf可以返回一个primitive类型就使用valueOf()转换,否则使用toString转换。
2、把object类型操作数转成primitive后,如果有任何一个操作数为字符类型,+执行的是字符串相连。
3、其他情况都把操作数转成number(可能为NaN),然后相加。
关系操作符:判断两个操作符是否满足某种关系,返回一个true or false
1、等和不等(==,!=,===,!==)
===严格等于,判断的时候,不会进行类型转换,判断过程如下:
a.如果两个操作数类型不同,他们就不严格相等。
b.如果两个操作数都为null,undefined,true,false则他们严格相等。
c.如果两个操作数有一个为NaN,他们不严格相等,即使两个都为NaN也一样。所以判断一个值是否是NaN,使用这个表达式:x!==x,该表达式唯一返回真的情况是x为NaN。
d.如果两个操作数为number,并且值相等,则他们严格相等,即使一个为-0,一个为0.
e.如果两个操作数都是string,并且在相同的位置包含一样的16位,则他们严格相等。注意,有些字符串看起来一样,但是实际上在16位内部表示上不同,所以不严格相等。
f.如果两个操作数引用的是同一个对象,数组,函数的话,则他们严格相等。但是不过对象不同,即使对象上的属性一样,他们也不严格相等。
==判断是否相等时,比较松,没有===那么严格的要求,判断的时候,必要时会进行类型转换,他们判断过程如下:
a.如果操作数类型相同,按严格相等判断,如果严格相等,则相等,否则不等。
b.如果操作数类型不同,通过如下规则和类型转换后,再进行判断:
1)如果一个为null,一个为undefined,他们相等:即null==undefined
2)如果一个为number,一个为string,把string转成number,再判断。如:2=="2"
3)如果其中一个为true,或者false,把true转成1,把false转成0,然后比较。如:false=="0"
4)如果一个为object,一个为number或者string,把object转成原始类型再比较,内置对象优先使用valueOf(内置的Date除外),其他对象优先使用toString(包括内置的Date)。
5)其他情况都不相等。
2、比较操作符(>,<=,<,<=)
比较操作符在必要的时候也会进行类型转换,在数字和字符串的比较的时候,JavaScript更倾向数字的比较,除非两个操作数都是字符串,才会进行字符串的比较。否则如果会把其中一个转换成数字,然后比较。
比较操作符的这个性质和+操作符是相反的,+操作符更倾向字符串的相连。比如"11"<3返回false,"11"<"3"返回true,1+2//=>3 1+"2"//=>"12"
3、in操作符,这个操作符判断左边的值是否是右边对象的一个属性,或者数组的一个下标值,所以要求左边的值为字符串或者可以转成字符串,要求右边的值为一个对象或者数组,比如:
var point={x:1,y:2},arr=[4,5,6]
"x" in point//true
"z" in point//false
"toString" in point//true,因为point继承了toString方法
0 in arr//true
"1" in arr//true
"4" in arr//false arr下标最大为2
4、instanceof操作符,这个操作符判断一个对象是否属于一个类,所以要求左边操作数为对象,右边为一个类(其实就是一个构造函数,JavaScript通过构造函数来定义类,并且初始化类)。
如果左操作数不是对象,返回false,如果右操作数不是函数,抛出TypeError异常。
例子:var d=new Date(2001,0,1);
d instanceof Date;//true
d instanceof Object//true,所有类都是Object类的子类,所以为true
5、赋值操作符(=,+=,-=...)
a=a+b与a+=b是有区别的,前者的a会求值两次,而后者只求值一次。所以,如果在表达式a中包含产生副作用的运算符(++,--),会有不一样的结果,否则这两个语句是等价的。
如:data[i++]*=2;与data[i++]=data[i++]*2;结果会不一样。
6、求值函数eval("2+3"):这个函数把一段JavaScript源代码计算出一个值,这个特性是解释性语言的特性。
7、一元delete操作符,可以删除对象上的一个属性,或者数组中的一个元素,如:
var obj={x:1,y:2},arr=[2,3,4];
delete obj.x;// "x" in obj returns false;
delete arr[1];//arr.length returns 2;[2,4]
8、一元void操作符,把一个操作数求值,然后把值舍弃,使其变为undefined。
这个操作符很少用到:<a href="javascript:void window.open();">Open New Window</a>
9、逗号操作”,“
例子:i=1,j=2,k=3;//
for(var i=0,j=10;i<j;i++){...}