ecma-262文档:https://262.ecma-international.org/

语言诞生

https://cn.history.js.org/

数据类型与表达式

undefined null

JavaScript 1.0 有两个特殊值,用于表示「缺少有用的数据值」。未初始化的变量会被设置为特殊值 undefined17。这也是程序在尝试访问对象中尚不存在的属性时所返回的值。在 JavaScript 1.0 中,可以通过声明和访问未初始化变量的方式,获取到 undefined 这个值。而值 null 则旨在表示某个预期存在对象值的上下文里「没有对象」。它是根据 Java 的 null 值建模的,有助于将 JavaScript 与 Java 实现的对象进行集成。在整个历史上,同时存在这样两个相似但又有显著不同的值导致了 JavaScript 程序员的困惑,很多人不确定应在何时使用哪个。

typeof null

typeof null 会返回字符串值 “object” 而不是 “null”。其实也可以说这与 Java 保持了一致,因为 Java 的所有值都是对象,而 null 本质上是表达「没有对象」的对象。但是,Java 缺少与 typeof 运算符等效的特性,并使用 null 作为未初始化变量的默认值。根据 Brendan Eich 的回忆,typeof null 的值是原始 Mocha 实现中抽象泄漏g的结果。null 的运行时值使用了与对象值相同的内部标记值进行编码,因此 typeof 运算符的实现就直接返回了 “object”,而无需任何额外的特殊处理。实践表明,这种选择对 JavaScript 程序员带来了很大的麻烦。他们通常想在尝试访问某个值的属性之前,先测试这个值是否确实是一个对象。但光是测试值的类型是否为 “object” 并不足以保护属性访问,因为尝试访问 null 的属性也会产生运行时错误。

对象

对象的属性既可以用作数据存储,也可以将行为与对象关联。那些值为函数的属性,可以作为对象的方法被调用。而作为对象方法被调用的函数,则可以通过关键字 this 的动态绑定来访问该对象。

对象原型

原型是一种特殊的对象,其自身属性与所有「由构造函数创建的对象」所共享。
对这种共享机制没有更进一步的说明,但可以发现原型对象具备如下特征:

  • 访问对象属性时,如果这个属性的名称在「与对象构造函数相关联的原型」上已被定义,那么将返回原型对象的属性值。
  • 对原型对象属性的添加或修改,对于通过「与原型相关联的构造函数」创建的现有对象,是立即可见的。
  • 为对象属性赋值时,会遮盖g18在「与对象构造函数相关联的原型」上定义的同名属性值。

    同名变量声明及参数

    var 声明的初始化过程(包括冗余声明在内)与「为初始化后的变量赋值」的语义相同。它们在函数体内按正常执行顺序,依次在(初始化阶段)到达时执行。
    脚本中可能有多个具有相同名称的 function 声明。在发生这种情况时,具有该名称的最后一个函数声明将被提升(hoist)到脚本顶部,并用这个名称初始化全局变量。所有其他同名的 function 声明都将被忽略。如果同时存在相同名称的全局 function 声明和全局 var 声明,它们都会指向相同的变量。在执行流程中遇到初始化器(即字面量)时,所有带初始化器的 var 声明都会覆盖函数值。

    this关键字

    直接调用函数而未为其限定(qualify)对象时,this 将被隐式设置为全局对象。
    而全局对象的属性包括了程序的所有全局变量。因此在直接调用函数时,this 所限定的属性引用,等价于对全局变量的引用。因为对 this 的处理取决于函数的调用方式,所以相同的 this 引用在不同的调用场景下,可能具有不同的含义。 ```javascript function setX(value) { this.x = value; } var obj = new Object; obj.setX = setX; // 将 setX 作为 obj 的方法

obj.setX(42); // 将 setX 作为方法调用 alert(obj.x); // 显示 42

setX(84); // 直接调用 setX alert(x); // 获取全局变量 x,显示 84 alert(obj.x); // 显示 42 ```