JavaScript 随记(2)

43 阅读4分钟

表达式和运算符

1、对象创建表达式

new Object();

这样的表达式就是对象创建表达式。特殊之处在于 new 关键字。

通过这种方式创建对象的实现过程是这样的:

  1. JavaScript 创建一个空对象 {}

  2. 让这个空对象调用构造函数。此时构造函数中的 this 指向就是这个空对象。

  3. 可以在构造函数中通过 this 给空对象添加属性。

  4. 被当成构造函数的函数并不会返回一个结果,新创建并初始化的对象就是整个对象创建表达式的值,除非显式地 return 了其它结果。

2、运算符

  • 除了常见的 +-*/ 运算符外,delete, typeof, instanceof, in 也属于运算符。

  • JavaScript 支持一个三元运算符:? :

  • 一元运算符和三元运算符的结合性都是自右向左,即优先从右侧开始运算。

  • 关于递增、递减运算符:假设 a = 1a++ 的值是 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 声明的变量;函数变量。