一、JS语言由三大部分组成
ECMAScript(核心):JavaScript 语言基础;
DOM(文档对象模型):规定了访问HTML和XML的接口;
BOM(浏览器对象模型):提供了独立于内容而在浏览器窗口之间进行交互的对象和方
二、变量
JS语言是弱类型语言,和其他强类型语言不通,JS中的变量是松散类型的,可以储存任务任何类型的数据,JS变量松散类型的本质,决定了变量只是在特定时间用于保存特定值的一个名字而已。由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变。
用var关键字声明的变量(块级变量可使用let关键字),未经初始化时,保存的是一个特殊的值——undefined。
可以在一条语句中声明多个变量,初始化或不初始化皆可,变量之间用逗号隔开。
用var关键字声明的变量是定义该变量的作用域中的局部变量,当使用var关键字声明了一个变量时,创建的这个变量是不可配置的,也就是说这个变量无法通过delete运算符删除。
1 var num1 = 10; 2 (function num() { 3 var num2 = 10; 4 delete num2; 5 console.log(num2); //10 6 })(); 7 delete num1; 8 console.log(num1); //10
在严格模式下,使用delete运算符删除var关键字声明的变量会导致SyntaxError.
省略var关键字会导致定义一个全局变量,但是不推荐这种做法。在严格模式下,给未声明的变量赋值会导致ReferenceError。
JS是基于词法作用域的语言:全局变量在整个程序中始终是有定义的,局部变量在声明它的函数体内以及其所嵌套的函数体内始终是有定义的。
在函数体内,局部变量的优先级高于同名的全局变量。
JS没有块级作用域,取而代之的是函数作用域:变量在声明它们的函数体内以及这个函数体嵌套的任何函数体内都是有定义的。
函数内部声明的变量和函数,要等到函数真正执行过后,才能有定义。
二、JS中的变量类型分为两种
1、基本类型
2、引用类型
基本类型有:Number、String、Boolean、Null、Undefiend;这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。
对于基本类型值,在复制变量的时候,会在新的变量上创建一个新值,这个新值是原值的一个副本,它们相互独立。
基本类型值之间的比较,只是单纯的值的比较。
引用类型值是保存在变量中的对象;引用类型值就是指对象。保存引用类型值的变量,实际上保存的是一个指向该对象的指针。
当复制保存着对象的某个变量时,复制的其实是指针;复制操作结束后,两个变量指向同一个对象。
对于引用类型值,可以为其添加属性和方法,也可以修改或者删除其属性和方法。
在为对象添加属性和方法时,操作的是实际的对象,因此,改变任何一个变量,都会影响另外一个变量
三、类型的检测
typeof
操作符(和 instanceof
一起)或许是 JavaScript 中最大的设计缺陷, 因为几乎不可能从它们那里得到想要的结果。
JavaScript 标准文档只给出了一种获取 [[Class]]
值的方法,那就是使用 Object.prototype.toString
。
// IE8 Object.prototype.toString.call(null) // "[object Object]" Object.prototype.toString.call(undefined) // "[object Object]" // Firefox 4 Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]"
为了检测一个对象的类型,强烈推荐使用 Object.prototype.toString
方法; 因为这是唯一一个可依赖的方式。正如上面表格所示,typeof
的一些返回值在标准文档中并未定义, 因此不同的引擎实现可能不同。
除非为了检测一个变量是否已经定义,我们应尽量避免使用 typeof
操作符。
四、全局变量
当JS解析器启动时,或者任何Web浏览器加载新页面的时候,它将创建一个新的全局对象,并给他一组定义的初始属性:
全局属性:比如undefined、Infinite、NaN
全局函数:比如isNaN()、parseInt()、eval()
构造函数,比如Date()、String()、Array()、Object()
全局对象:比如Math、Json
初次创建的时候,全局对象定义了JS中所有的预定义全局值。
如果代码声明了一个全局变量,这个全局变量就是全局对象的一个属性。
全局变量作用于全局作用域,在JS代码中的任何地方都是有定义的。
五、变量的声明、定义与初始化
声明——给变量一个名字,宣告它从此刻开始存在;
定义——给变量分配一个存储空间;
初始化——给变量的存储空间赋值。
由于JS是一种动态语言,其变量的类型是不固定的,可以随着保存值的变化而变化,所以其定义变得无关紧要。
六、变量声明提升
JS在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。
声明提升,这步操作是在JS引擎“预编译”阶段实现的,是在代码开始运行之前。
七、名字解析顺序
JS中一个名字可能以4种方式进入作用域,其优先级如下:
(1)语言内置——所有作用域中都有arguments对象和this对象;
(2)以声明的方式声明的函数
(3)形式参数
(4)变量声明——不会影响同名的函数声明或者形式参数声明