表达式和运算符
1、对象创建表达式
new Object();
这样的表达式就是对象创建表达式。特殊之处在于 new 关键字。
通过这种方式创建对象的实现过程是这样的:
-
JavaScript 创建一个空对象
{}。 -
让这个空对象调用构造函数。此时构造函数中的
this指向就是这个空对象。 -
可以在构造函数中通过
this给空对象添加属性。 -
被当成构造函数的函数并不会返回一个结果,新创建并初始化的对象就是整个对象创建表达式的值,除非显式地
return了其它结果。
2、运算符
-
除了常见的
+-*/运算符外,delete, typeof, instanceof, in也属于运算符。 -
JavaScript 支持一个三元运算符:
? :。 -
一元运算符和三元运算符的结合性都是自右向左,即优先从右侧开始运算。
-
关于递增、递减运算符:假设
a = 1,a++的值是 1,称为后增量运算符,返回进行增量计算之前的值;++a的值是 2,称为前增量运算符,返回进行增量计算后的值。 -
关系运算符在比较数和字符串时,优先将字符串转换为数进行比较。
-
关系运算符
>, <, >=, <=只能针对数和字符串进行比较,其它类型的变量将进行类型转换。 -
对象在进行关系运算时:
==比较时,只有引用相同的对象为true;<, >等比较时,会被转换为字符串进行比较,转换结果为"[object Object]"是相等的。总结:两个不同的对象之间的关系是>=或<=。 -
字符串之间的比较,使用
String.prototype.localeCompare()方法更加精确,该方法可以根据不同的语言系统进行精确的比较。 -
NaN在进行关系运算时,全部为false。 -
in运算符左侧的操作数为字符串或可以转换成字符串,右侧操作数为对象(包括数组)。当右侧操作数为数组时,左侧操作数表示的是数组的索引而不是数组的元素。也就是说,in运算符查找的是 “key 值”。 -
instanceof运算符:所有对象都是Object的实例。
3、逻辑表达式
-
逻辑与
&&:当左操作数为假时,直接返回左操作数;当左操作数为真时,直接返回右操作数。 -
逻辑或
||:和逻辑与同理。
4、eval
-
eval接收的参数是字符串,而且是有意义的字符串,否则将抛出错误语法异常。 -
eval的作用域取决于调用它的变量作用域环境。比如说:在一个函数中被调用,那么它的作用域便是该函数的作用域,可以访问函数中的局部变量,也可以访问外部的全局变量。 -
如果
eval在一个函数中被调用,那么它的执行上下文取决于函数的执行上下文。 -
eval在严格模式下不允许使用别名调用。当通过别名调用时,将会使用全局的上下文环境作为eval的执行上下文。
下面是一个代码示例:
var geval = eval; // 使用别名调用 eval 将是全局 eval
var x = "global", y = "global"; // 两个全局变量
function f () { // 函数内执行的是局部 eval
var x = "local"; // 定义局部变量
eval("x += 'changed';"); // 直接 eval 更改了局部变量的值
return x; // 返回更改后的局部变量
}
function g () { // 这个函数内执行了全局 eval
var y = "local"; // 定义局部变量
geval("y += 'changed';"); // 间接调用改变了全局变量的值
return y; // 返回未更改的局部变量
}
console.log(f(), x); // 更改了局部变量: 输出"localchanged global"
console.log(g(), y); // 更改了全局变量: 输出"local globalchanged"
5、typeof
-
typeof undefined === "undefined" -
虽然数组和函数的本质都是对象,但
typeof函数的结果却是"function",不仅如此,所有可执行对象都是如此,比如说:class类。
6、delete
-
使用
delete运算符删除一个数组元素,数组的长度不发生改变,被删除的元素位置显示empty,输出为undefined。 -
delete运算的返回值为true/false,表示删除的成功与否。 -
有些变量不允许被删除,比如说:一些内置核心和客户端属性;用
var/const/let声明的变量;函数变量。