原始表达式
JavaScript中原始表达式包含常量或直接量、关键字和变量
1.23; //数字直接量
"hello"; //字符串直接量
/pattern/; //正则表达式直接量
JavaScript中一些保留着构成来原表达式
true; //返回一个布尔值:真
false; //返回一个布尔值:假
null; //返回一个值:空
this; //返回当前对象
最后第三种原始表达式是变量
i; //返回变量i的值
sum; //返回sum的值
undefined; //undefined是全局变量,和null不同,它不是一个关键字
当JavaScript代码中出现来标识符,JavaScript会将其当做变量去查找它的值,如果变量名不存在,表达式结果为undefined。然而,在ECMAScript5的严格模式下,对不存在的变量进行求值会抛出一个引用错误异常
对象和数组的初始化表达式
初始化的结果是一个新创建的数组。数组的元素是逗号分隔的表达式的值:
[]; //一个空数组:[]内留空即表示该数组没有任何元素
[1 + 2, 3 + 4]; //拥有两个元素的数组,第一个是3,第二个是7
数组表达式中的元素初始化表达式也可以是数组初始化表达式。也就是说,这些表达式是可以嵌套的
var matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充undefined。例如,下面这个数组包含5个元素,其中三个元素是undefined
var sparseArray = [1, , , , 5];
对象初始化和数组初始化表达式非常类似,只是方括号被花括号代替,并且每个子表达式都包含一个属性名和一个冒号作为前缀
var p = {x: 2.3, y: -1.2}; //一个拥有两个属性成员的对象
var q = {}; //一个空对象
q.x = 2.3; q.y; //q的属性成员和p的一样
对象直接量也可以嵌套,比如
var rectangle = {
upperLeft: {x: 2, y: 2},
lowerRight: {x: 4, y: 5}
};
对象直接量中的属性名称可以是字符串而不是标识符
var p = {x: 3, y: 4};
var side = 1;
var square = {
"upperLeft": {x: p.x, y: p.y},
'lowerRight': {x: p.x, y: p.y}
};
函数定义表达式
//这个函数返回传入参数值的平方
var square = function (x) {
return x * x;
}
属性访问表达式
var o = {x: 1, y: {z: 3}}; //一个示例对象
var a = [o, 4, [5, 6]]; //一个包含这个对象的示例数组
o.x;
o.y.z;
o["x"];
a[1];
a[2]["1"]
a[0].x
调用表达式
JavaScript中的调用表达式是一种调用函数或方法的语法表示
function f() {
}
f(); //f是一个函数表达式
Math.max(1,2,3); //Math.max是一个函数
对象创建表达式
new Object();
new Point(2, 3);
如果一个对象创建表达式不需要传入任何参数给构造函数的话,那么这对圆括号可以省略掉
new Object
new Date
运算符概述
运算符 | 操作 |
---|---|
++ | 前/后增量 |
-- | 前/后减量 |
- | 求反,减 |
+ | 转换为数字,加,字符串连接符 |
~ | 按位求反 |
! | 逻辑非 |
delete | 删除属性 |
typeof | 检测操作数类型 |
void | 返回undefined值 |
* | 乘 |
/ | 除 |
% | 求余 |
<< | 左位移 |
>> | 有符号右移 |
>>> | 无符号右移 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
instanceof | 测试对象类 |
in | 测试属性是否存在 |
== | 判断相等 |
!= | 判断不等 |
=== | 判断恒等 |
!== | 判断非恒等 |
& | 按位与 |
^ | 按位异或 |
| | 按位或 |
&& | 逻辑与 |
逻辑或 | |
?: | 条件运算符 |
= | 变量赋值或对象属性赋值 |
*= | 运算且赋值 |
/= | 运算且赋值 |
%= | 运算且赋值 |
+= | 运算且赋值 |
-= | 运算且赋值 |
&= | 运算且赋值 |
^= | 运算且赋值 |
<<= | 运算且赋值 |
>>= | 运算且赋值 |
>>>= | 运算且赋值 |
, | 忽略第一个操作数,返回第二个操作数 |
操作数的个数
二元运算符
将两个表达式合并成一个稍复杂的表达式
一元运算符
将一个表达式转换为另一个稍微复杂的表达式
三元操作符
条件判断运算符“?:”,它将三个表达式合并成一个表达式。
算术表达式
“+”运算符
1 + 2; //=> 3
"hello" + " " + "there"; //=>"hello there"
"1" + "2" //=> "12"
加号的转换规则优先考虑字符串连接,如果其中一个操作数是字符串或者转换为字符串的对象。另外一个操作数将会转换为字符串,加法将进行字符串的连接操作。如果两个操作都不是类字符串的,那么都将进行算数加法运算。
1 + 12; //=>4:加法
"1" + "2"; //=> "12":字符串连接
"1" + 2; //=>"12":字符串连接
1 + {}; //=>"1[object object]"
true + true; //2:布尔值转换为数字后做加法
2 + null; //2:null转换为0后做加法
2 + undefined //NaN:undefined 转换为NaN后做加法
运算结果是依赖于运算符的运算顺序的,
1 + 2 + "blind mice"; //=>"3 blind mice"
1 + (2 + "blind mice"); //=>"12 bind mice"
一元算术符
一元运算符作用于一个单独的操作数,并产生一个新值
"+"和"-"是一元运算符,也是二元运算符
一元加法(+)
一元加法运算符把操作数转换为数字(或者NaN),并返回这个转换后的数字。如果操作数本身就是数字,则直接返回这个数字
一元减法(-)
当“-”用来做一元运算符是,它会根据需要把操作数转换为数字,然后改变运算结果的符号
递增(++)
递增(++)运算符对其操作数进行增量操作,运算符将操作数转换为数字,然后给数字加1,并将加一后的数值重新赋值给变量,数组元素或者对象属性
当在运算符在操作数之前,称为“前增”运算符,当在运算符之后,称为“后增”运算符
var i = 1, j = ++i; //i和j的值都是2
var i = 1, j = i++; //i是2,j是1
递减(-- )
当递减运算符在操作数之后,操作数减1并返回减1之前的值。当递减运算符在操作符的右侧时,运算符和操作数之间不能有换行符。
位运算符
按位与(&)
位运算符“&”对它的整型操作数逐位执行布尔与(and)操作。只有两个操作数中相应的位都是1,结果中的这一位才是1.
按位或(|)
位运算符“|”对它的整型操作数逐位执行布尔或(OR)操作。如果其中一个操作数相应的位为1,或者两个操作数相应位都是1,那么结果中的这一位就为1.
按位异或(^)
位 运算符“|” 对 它的 整型 操 作数 逐 位 执行 布尔 异或( XOR) 操作。 异或 是指 第一个 操 作数 为 true 或第二个操作数中只有一个相应位为1(不能同时为1),那么结果中的这一位就是1
左移(<<)
将第一个操作数的所有二进制进行左移操作,移动的位数由第二个操作数指定,移动的位数是0~31之间的一个整数。将一个值左移1位相当于它乘以2,左移2位相当于成于4
带符号右移(>>)
如果第一个操作数是整数,移位后用0填补高位:如果第一个操作数是负的,移位后就用1填补高位。将第一个值右移1位,相当于用他除2,右移两位相当于除以4
无符号右移(>>>)
运算符“>>>”和运算符">>"一样,只是左边的高位总是填补0,与原来的操作数符号无关
关系表达式
关系表达式总是返回一个布尔值,通常在if、while或者for语句中使用关系表达式。用以控制程序的执行流程。
相等和不等运算符
= //得到或赋值
== //相等
=== //严格相等
!= //不等
!== //严格不相等
//(赋值、相等、恒等)
严格 相等 运算符“===” 首先 计算 其 操 作数 的 值, 然后 比较 这 两个 值, 比较 过程 没有 任何 类型 转换:
- 如果 两个 值 类型 不 相同, 则 它们 不相等。
- 如果 两个 值 都是 null 或者 都是 undefined, 则 它们 不相等。
- 如果 两个 值 都是 布尔 值 true 或 都是 布尔 值 false, 则 它们 相等。
- 如果 其中 一个 值 是 NaN, 或者 两个 值 都是 NaN, 则 它们 不相等。 NaN 和 其他 任何 值 都是 不相等 的, 包括它本身,通过x!==x来判断x是否为NaN,只有在x为NaN的时候,这个表达式的值才为true
- 如果 两个 值 为 数字 且 数值 相等, 则 它们 相等。 如果 一个 值 为 0, 另一个 值 为-0, 则 它们 同样 相等。
- 如果两个引用值指向同一个对象,数组或函数,则它们是相等的。如果指向不同的对象,则它们是不相等的,尽管两个对象具有完全一样的属性
相等运算符“==”和恒等运算符相似,但是相等运算符的比较严格。如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较
- 如果 两个 操 作数 的 类型 相同, 则 和 上文 所述 的 严格 相等 的 比较 规则 一样。 如果 严格 相等, 那么 比较 结果 为 相等。 如果 它们 不严 格 相等, 则 比较 结果 为 不相等。
- 如果两个操作数类型不同,“==”相等操作符也可能会认为它们相等。、
- 如果一个值是null,另一个是undefined则它们相等
- 如果一个值是数字,另一个是字符串,先将字符串转换为数字,然后使用转换后的值进行比较
- 如果其中一个值是true,增将其转换为1再进行比较,false则为0
比较运算符
比较运算符用来检测连个操作数的大小关系(数值大小或者字母表的顺序)
小于(<)
如果第一个操作数小于第二个操作数,则“<”运算符的计算机结果为true;否则为false
大于(>)
如果第一个操作数大于第二个操作数,则“>”运算符的计算结果为true;否则为false
小于等于(<=)
如果第一个操作数小于或者等于你第二个操作数,则“<=”运算符的计算结果为true;否则为false。
大于等于(>=)
如果第一个操作数大于或者等于第二个操作数,则“>=”运算符结果为false;否则为true;
比较操作数可能是任意类型。然而,只有数字和字符串才能真正执行比较操作,因此那些不是数字个字符串的操作数都将进行类型转换
- 如果操作数为对象,那么这个对象将依照转换规则转换为原始值:如果valueOf()返回一个原始值,那么直接使用这个原始值。否则,使用toString()的转换结果进行比较操作。
- 在对象转换为原始值之后,如果链各个操作数都是字符串,那么将依照字母表的顺序对两个字符串进行比较。
- 在对象转换为原始值之后,如果至少有一个操作数不是字符串,那么两个操作数都将转换为数字进行数值比较。0和-0是相等的。Infinity比其它任何数字都大(本身除外),如果其中一个操作数是(转换后是)NaN,那么比较操作符总是返回false
对于那些不区分字母大小写的比较来说,则需要首先将字符串全部换为小写字母或者大写字母,通过String.toLowerCase()和String.toUpperCase()做大小写的转换。
对于数字和字符串操作符来说,加号运算符和比较运算符的行为都有所不同,前者更偏爱字符串,如果它的其中一个操作符是字符串的话,则进行字符串连接操作。而比较运算符则更加偏爱数字,只有在两个操作符都是字符串的时候,才会进行字符串的比较:
1 + 2; //加法,结果是3
"1" + "2"; //字符串连接,结果是"12"
"1" + 2; //字符串连接,2转换为"2",结果是"12"
11 < 2; //数字的比较,结果为false
"11" < "13"; //字符串比较,结果为true
"11" < 3; //数字比较,结果为false
"noe" < 3; //数字的比较,“one”转换为NaN,结果为false
in运算符
in运算符希望它的左操作数是一个字符串或可以转换为字符串,希望它的右操作数是一个对象。如果右侧的对象拥有一个名为左操作数值得属性名,那么表达式返回true
var point = {x: 1, y: 1}; //定义一个对象
"x" in point; //=> true :对象有一个名为“x”的属性
"z" in point; //=>false:对象中不存在名为"z"的属性
"toString" in point; //true 对象继承了toString()方法
var data = [7,8,9]; //拥有三个元素的数组
"0" in data; //=> true 数组包含元素"0"
1 in data; //=> true 数字转换为字符串
3 in data; //=>false 没有索引为3的元素
instanceof运算符
instanceof运算符希望左操作数是一个对象,右操作数标识对象的类。如果左侧的对象时右侧类的实例,则表达式返回true;否则返回false。
var d = new Date();
d instanceof Date; //计算结果为true,d是由Date()创建的
d instanceof Object; //计算结果为true,所有的对象都是Object的实例
d instanceof Number; //计算结果为false,d不是Number对象
var a = [1, 2, 3];
a instanceof Array; //计算结果为true,a是一个数组
a instanceof Object; //计算结果为true,所有的数组都是对象
a instanceof RegExp; //计算结果为false,数组不是正则表达式