第四章 表达式和运算符
- 原始表达式:表达式到最小单位
- 对象和数组的初始化表达式:“对象直接量”——{},“数组直接量”——()
- 函数定义表达式:“函数直接量”——function() {}
- 属性访问表达式:点操作符后面跟的是合法的标识符,其他情况则需要换用方括号
- 运算符:typeof,void,in,instanceof,delete
- 操作数的个数、类型,结果的类型
- 左值:lval
- 运算符优先级
- 运算符的结合性
- 算数表达式
- 关系表达式:“相等/不想等”,比较运算符,in运算符,instanceof运算符
- 逻辑表达式
- && 的三层次理解:
- 1、当操作数都是布尔值时,对其进行布尔与操作
- 2、常用来连接两个关系表达式,&& 可以对真值和假值进行布尔与操作
- 3、运算符先计算左操作数的值,若为假,则直接返回false;若为真,则返回右操作数的计算结果,这种行为有时称作“短路”
- 表达式计算:全局函数eval()——eval(),全局eval(),严格eval()
- 其他运算符:typeof,真正的函数 VS 可执行对象,都返回“function”。delete。void。
eval()只有一个参数。如果传入的参数不是字符串,它直接返回参数。如果是字符串,则将字符串当作js代码编译,编译失败则抛出语法错误(SyntaxError)异常。如果编译成功,则开始执行这段代码,并返回字符串中的最后一个表达式或语句的值,如果最后一个表达式或语句没有值,则返回undefined。
关于eval()最重要的是,它使用了调用它的变量作用域环境。也就是说,它查找变量的值/定义新变量/函数的操作和局部作用域中的代码一样。
当然,如果在最顶层代码调用eval(),会作用于全局变量和全局函数。
事实上,eval()的字符串执行时的上下文环境和调用函数的上下文环境是一样的,这不能使其作为函数的一部分来运行。如下例
var foo = function(a) {
eval(a);
}
foo("return;");
全局eval()
当通过别名调用eval()时,eval()会将其字符串当作顶层的全局代码来执行。执行的代码可能会定义新的全局变量或全局函数,或者给全局变量赋值,但却不能使用或修改主调函数中的局部变量,因此,这不会影响函数内的代码优化。
严格eval()
严格模式下,eval()执行的代码段可以查询和改变局部变量,但不能在局部作用域中定义新的局部变量或函数。eval被列为保留字,更像一个运算符,不能用别名覆盖。