JavaScript表达式与运算符详解
JavaScript表达式与运算符详解
1. 原始表达式
原始表达式是构成JavaScript表达式的基本单元,主要包括:
- 常量(直接量):在程序中直接出现的固定值
- 变量:代码中的标识符会被JavaScript视为变量,如果变量未定义,将返回undefined。在ES5严格模式下,会抛出引用错误异常
- 关键字:与其他关键字不同,this不是一个常量,它在程序的不同位置返回不同的值。在方法内部,this指向调用该方法的对象
2. 对象和数组初始化表达式
对象初始化表达式(对象直接量)
形式:{属性名1: 属性值1, 属性名2: 属性值2, ...}
- 对象可以嵌套定义
- 属性名可以是字符串
数组初始化表达式(数组直接量)
形式:[元素1, 元素2, 元素3, ...]
- 当逗号之间的元素被省略时,空位会被填充为undefined
- 数组可以嵌套
3. 函数定义表达式(函数直接量)
形式:function(参数列表){ 函数体 }
var calculateSquare = function(number) {
return number * number;
}; // 计算平方并赋值给calculateSquare变量
4. 属性访问表达式
有两种形式:
- 形式1:对象名.属性名
- 形式2:对象名[属性名] 或 数组名[索引]
无论哪种形式,如果属性不存在,整个表达式的值都是undefined。当属性名是通过计算得出而不是固定值时,必须使用形式2。
var data = {value: 1, nested: {inner: 2}};
var list = [0, 4, [5, 6]];
data.value // 返回1
data.nested.inner // 返回2
data["value"] // 返回1
list[1] // 返回4
list[2][1] // 返回6
list[data.value].value // 返回1
5. 调用表达式
用于调用或执行函数或方法。
函数调用
形式:函数名(参数列表)
通常使用全局对象作为this的值,在ES5严格模式中使用undefined作为this的值。
方法调用
形式:属性访问表达式(参数列表)
执行方法时,函数体中的this指向调用它的对象或数组。
6. 对象创建表达式
创建一个新对象并调用一个函数(构造函数)来初始化该对象的属性。
形式:new 构造函数名(参数列表)
如果不需要向构造函数传递任何参数,可以省略参数列表和圆括号:new 构造函数名
7. 运算符概述
- JavaScript中的运算符可分为标点符号运算符(如"+"和"=")和关键字运算符(如"delete"和"instanceof")
- 根据操作数的个数,可分为一元运算符(如"-")、二元运算符(如"*")和三元运算符(如"?:")
- 求余运算符计算第一个操作数对第二个操作数的模,结果的符号与第一个操作数的符号一致
- JavaScript会根据需要对操作数进行类型转换
- 所有值要么是真值要么是假值
- 运算符的优先级可以通过使用圆括号来重写
- 属性访问表达式和调用表达式的优先级高于所有其他运算符
- 结合性指定了具有相同优先级的运算符的运算顺序
运算符的副作用
普通运算符执行后的结果通常不会影响程序的运行状态,但有些运算符会产生副作用:
- 赋值运算符("="):给变量或属性赋值,使用该变量或属性的表达式的值会改变
- delete运算符:删除属性类似于给属性赋值为undefined
左值
左值是指可以出现在赋值运算符左边的表达式。JavaScript中的变量、对象属性和数组元素都是左值。
8. 算术表达式
加法运算符("+")
可以对两个数字进行加法运算,也可以连接两个字符串。其他情况下的行为如下:
- 优先考虑字符串连接,如果两个操作数都不是类字符串的,将进行加法运算
- 具体行为涉及类型转换规则
一元算术运算符
- 一元加号("+"):将操作数转换为数字并返回
- 一元减号("-"):将操作数转换为数字并改变符号
- 递增("++")和递减("--"):
- 前增量/前减量:先改变操作数的值,然后返回改变后的值
- 后增量/后减量:先返回操作数的原始值,然后改变操作数的值
位运算符
对二进制数据进行运算,返回数字。操作对象是32位整数。
- 按位与("&"):逐位执行布尔与运算
- 按位或("|"):逐位执行布尔或运算
- 按位异或("^"):逐位执行布尔异或运算
- 按位非("~"):将操作数逐位取反
- 左移("<<"):将二进制位左移,新位置以0填充
- 带符号右移(">>"):保留符号位进行右移
- 无符号右移(">>>"):不考虑符号位进行右移
9. 关系表达式
判断两个值之间的关系,返回true或false。
相等和不等运算符
- 相等("==")和不等("!="):会进行类型转换后再比较
- 严格相等("===")和严格不等("!="):不进行类型转换,直接比较值和类型
比较运算符
包括"<"、">"、"<="、">="。只有数字和字符串才能执行真正的比较运算,其他类型会进行转换。
in运算符
左操作数是一个字符串,右操作数是一个对象,如果右侧对象拥有该属性名,返回true。
instanceof运算符
左操作数是一个对象,右操作数是一个函数,如果左侧对象是右侧函数的实例(包括父类),返回true。
10. 逻辑表达式
- 逻辑与("&&"):短路运算,如果左操作数为假值,返回左操作数,否则返回右操作数
- 逻辑或("|"):短路运算,如果左操作数为真值,返回左操作数,否则返回右操作数
- 逻辑非("!"):将操作数的布尔值取反
11. 赋值表达式
包括基本赋值运算符("=")和复合赋值运算符("+="、"-="等)。
12. 表达式计算
eval()函数
eval()函数会将字符串作为JavaScript代码执行,其行为类似于在局部作用域中执行代码。
var executeEval = eval; // 为eval创建别名
var globalVar = "global", localVar = "global";
function testDirectEval() {
var x = "local";
eval("x += ' modified';"); // 直接eval修改局部变量
return x;
}
function testIndirectEval() {
var y = "local";
executeEval("y += ' modified';"); // 间接eval修改全局变量
return y;
}
console.log(testDirectEval(), globalVar); // 输出:local modified global
console.log(testIndirectEval(), localVar); // 输出:local global modified
在ES5严格模式下,eval执行的代码可以查询或更改局部变量,但不能定义新的变量或函数。
13. 其他运算符
条件运算符("?:")
JavaScript中唯一的三元运算符,形式为:条件表达式 ? 表达式1 : 表达式2
typeof运算符
返回表示操作数类型的字符串,可能的返回值包括:"undefined"、"boolean"、"number"、"string"、"function"、"object"等。
delete运算符
删除对象属性或数组元素,成功返回true,失败返回false。通过var声明的变量和通过function定义的函数不可删除。
void运算符
忽略操作数的计算结果并返回undefined,常用于链接中防止页面跳转。
<a href="javascript:void window.open();">打开新窗口</a>
逗号运算符(",")
先计算左操作数,再计算右操作数,最后返回右操作数的值。总是会计算左操作数,但忽略其结果。