Javascript学习笔记(二)Javascript核心之表达式和运算符
最简单的表达式是直接量或者变量名,直接表达式的值是它本身,变量表达式的值是该变量所存放或引用的值.
Javascript的运算符
优先级 |
A |
运算符 |
运算数类型 |
所执行的操作 |
---|---|---|---|---|
15 |
L |
. |
对象,标识符 |
属性存取 |
L |
[] |
数组,整数 |
数组下标 |
|
L |
( ) |
函数,参数 |
函数调用 |
|
R |
new |
构造函数调用 |
创建新对象 |
|
14 |
R |
++ |
lvalue |
先递增或后增运算(一元的) |
R |
-- |
lvalue |
先递减或后递减运算(一元的) |
|
R |
- |
数字 |
一元减法(负) |
|
R |
+ |
数字 |
一无加法 |
|
R |
~ |
i整数 |
按位取补码的操作(一元的) |
|
R |
! |
布尔值 |
取逻辑补码的操作(一元的) |
|
R |
delete |
lvalue |
删除一个属性(一元的)的定义 |
|
R |
typeof |
任意 |
返回数据类型(一元的) |
|
R |
void |
任意 |
返回未定义的值(一元的) |
|
13 |
L |
*, /, % |
数字 |
乘法,除法,取余运算 |
12 |
L |
+, - |
数字 |
加法,减法运算 |
L |
+ |
字符串 |
字符串连接 |
|
11 |
L |
<< |
整数 |
左移 |
L |
>> |
整数 |
带符号扩展的右移 |
|
L |
>>> |
整数 |
带零扩展的右移 |
|
10 |
L |
<, <= |
数字或字符串 |
小于或小于等于 |
L |
>, >= |
数字或字符串 |
大于或大于等于 |
|
L |
instanceof |
对象,构造函数 |
检查对象类型 |
|
L |
in |
字符串,对象 |
检查一个属性是否存在 |
|
9 |
L |
== |
任意 |
相等性检测 |
L |
!= |
任意 |
不等性检测 |
|
L |
=== |
任意 |
等同性检测 |
|
L |
!== |
任意 |
非等同性检测 |
|
8 |
L |
& |
整数 |
按位与操作 |
7 |
L |
^ |
整数 |
按位异操作 |
6 |
L |
| |
整数 |
按位或操作 |
5 |
L |
&& |
布尔值 |
逻辑与操作 |
4 |
L |
|| |
布尔值 |
逻辑或操作 |
3 |
R |
?: |
布尔值,任意,任意 |
(由三个运算数构成的)条件运算符 |
2 |
R |
= |
lvalue, 任意 |
赋值运算 |
R |
*=, /=, %=, +=, -=, <<=, |
lvalue, 任意 |
带操作的赋值运算 |
|
1 |
L |
, |
任意 |
多重计算的操作 |
字符串不能乘法运算,但是可能的情况下,JavaScript将表达式转换为适当的类型,如:"3"*"5",会得到15,而不是"15";另外运算符"+"对数字运算执行加法操作,对字符串执行连接操作,如果是一个数字和一个字符串,那么就把数字转换成字符串,如: "1"+0产生字符串"10"等。
在Javascript中,变量,对象的属性和数组的元素都是lvalue型的.
下面规则用于===运算符比较的两个值是否完全相乘
●如果两个值类型不同,它们就不同;
●如果两个值都是数字,而且值相同,那么除非其中一个或两个都是NaN(这种情况它们不是等同的),否则它们是等同的.值NaN永远不会与其他任何值等同,包括自身.要检测一个值是否是NaN,可以使用全局函数isNaN().
●如果两个值都是字符串,而且在串中同一位置上的字符完全相同,那么它们就完全等同.如果字符串的长度或内容不同,它们就不是等同.注意,在某些情况下.Unicode标准允许用多种方法对同样的字符串进行编码.但是,从效率方面考虑.Javascript字符串比较操作严格地逐个转换成了"范式".另一种比较字符串的方法,请参阅"String.localeCompare()"
●如果两个值都是truea或者都是false,那么它们等同.
如果两个值引用的是同一个对象,数组或函数,那么它们完全等同.如果它们引用的是不同的对象(数组或函数),它们就不完全等同,即使这两个对象具有完全的属性或两个数组具有完全相同的元素.
●如果两个值都是null或都是undefined,它们完全相同.
下面的规则用于判定==运算符比较的两个值是否相等:
●如果两个值具有相同的类型,那么就检测它们的等同性.如果两个值完全相同,它们就相等.如果它们不完全相同,则它们不相等.
●如果两个值的类型不同,它们仍然可能相等.用下面的规则和类型转换来检测它们的相等性:
如果一个值时null,一个值时undefined,它们相等;
如果一个值时数字,一个是字符串,把字符串转换为数字,再用转换后的值进行比较;
如果两值为true和false,分别转换为1和0,再比较;
如果一个值是对象,另一个值是数字或字符串将对象转换成原始类型的值再进行比较,可以用对象的toString()方法或valueOf()方法将对象转换成原始类型的值.Javascript核心语言的内部类先尝试valueOf()转换,再尝试toString()转换,但是对于Date类,则先执行toString()转换.不属于Javascript核心语言的对象则可以采用javascript实现定义的方式把自身转换成原始数值.
其他的数值组合是不相等的.
比较运算符(<,>,<=,>=)的运算数可以是任意类型的,但是比较运算只能在数字和字符串上执行,所以不是数字或字符串类型的运算数将被转换成数字或字符串再比较。比较和转换的规则如下:
如果两个运算数都是数字,或者都被转换成了数字,那么将采取数字比较.
如果两个运算数都是字符串,或者都被转换成了字符串,那么将作为字符串进行比较.
如果一个运算数是字符串或者被转换成字符串,而另一个运算数是数字或者被转换成了数字,那么运算符会将字符串转换成数字,然后执行数字比较.如果字符串不代表数字,它将被转换为NaN,比较的结果是false.
如果对象可以被转换成数字或字符串,javascript将执行数字转换.例如,可以从数字的角度比较Date对象,也就是说,比较两个日期,以判断哪个日期早于另一个日期是有意义的.
如果运算数都不能被成功地转换成数字或字符串,运算符总是返回false.
如果某个运算数是NaN,或被转换成了NaN,比较运算符总是生成false.
字符串的比较操作采用每个字符串中的字符在Unicode编码中的数值,逐个字符比较。要了解强字符串比较算法,请参阅String.localeCompare().
in运算符:in运算符要求其左边的运算数是一个字符串,右边是一个对象或数组,如果左边的值是右边值得一个属性名,返回true。如:
var point = {x:1,y:1}; //定义一个对象
var has_x = "x" in point; //true
var has_z = "z" in point; //false,它不是一个3维点
var ts = "tostring" in point //继承属性;true
instanceof运算符:instanceOf运算符要求其左边运算数是一个对象,右边是个对象类的名字。如果该运算符左边的对象是右边类的一个实例,它返回false,否则返回true.在javascript中,对象类是由用来初始化它们的构造函数定义的,因此,instanceof运算符 右边的运算数应该是一个构造函数的名字.注意,所有对象都是Object类的实例.如果instanceof的左运算数不是对象,或者右边的运算数是一个对象,而不是一个构造函数,它将返回false.另外,如果它右边运算数根本就不是对象,它将返回一个运行时错误.
在对字符串进行运算时,注意:
1+2 //加法;3
"1" + "2" //连接运算;"12"
"1" + 2 // 连接运算;"12"
11<3 //数字比较;false
"11" < "3" //字符串比较;true
"11" < 3 //数字比较 ;true
"one"<3 // "one"转换为NaN;false
s = 1+2+" blind mice " //"3 blind mice"
t = "blind mice "+1+2 //"blind mice 12"
逻辑非运算符(!)对任何值做两次运算(即!!x)都可以将它转成一个布尔值。
带操作符的赋值运算
Operator |
Example |
Equivalent |
---|---|---|
+= |
a += b |
a = a + b |
-= |
a -= b |
a = a - b |
*= |
a *= b |
a = a * b |
/= |
a /= b |
a = a / b |
%= |
a %= b |
a = a % b |
<<= |
a <<= b |
a = a << b |
>>= |
a >>= b |
a = a >> b |
>>>= |
a >>>= b |
a = a >>> b |
&= |
a &= b |
a = a & b |
|= |
a |= b |
a = a | b |
^= |
a ^= b |
a = a ^ b |
new运算符:创建新实例。
delete运算符:delete是一个一元运算符,它将删除运算数所指定的对象的属性、数组元素或变量。若删除成功返回true,否则返回false。并非所有的属性和变量都可以删除,某些内部的核心属性和客户端属性不能删除,用var语句声明的变量也不能被删除。如果delete使用的运算数是一个不存在的属性,它将返回true.看以下几个例子:
var o = {x:1, y:2}; // 定义一个变量; 初始化为一个对象
delete o.x; // 删除对象属性; true
typeof o.x; //属性不存在; "undefined"
delete o.x; // 删除不存在的属性; true
delete o; // 不能删除已声明的变量; false
delete 1; // 不能删除整数; true
x = 1; // 不用var关键字,隐式声明一个变量
delete x; // 可以删除这种变量; true
x; // 运行时出错: x未被定义
注意,删除属性,变量或数组元素不只是把它们的值设置为undefined.当删除一个属性后,该属性将不再存在.
注意,delete所能影响的只是属性值,并不能影响被这些属性引用的对象.如:
var my = new Object( ); // 创建一个名为 "my"的对象
my.hire = new Date( ); // my.hire引用一个 Date 对象
my.fire = my.hire; // my.fire 引用同一个对象
delete my.hire; // hire 属性被删除; true
document.write(my.fire); // 但是my.fire仍引用那个Date对象
void运算符:void运算符是一元运算符,可以出现在任何类型的操作数之前。它总是舍弃运算数的值,返回undefined。常用在客户端的javascript:URL中。如:<a href="javascript:void window.open();">Open new Window</a>
void的另一个用途是专门生成undefined值,由undefined在javascript1.5中实现,void 0的使用是在考虑向后兼容性。
"[]"来存取数组的元素,"."来存取对象的元素.