1.基本类型和引用类型
JavaScript 变量可以用来保存两种类型的值:基本类型值和引用类型值。基本类型的值源自以下5种基本数据类型:Undefined、Null、Boolean、Number 和String。基本类型值和引用类型值具有以下特点:
1、基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。
2、 引用类型的值是对象(Object),保存在堆内存中;包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。q
确定一个值是哪种基本类型可以使用typeof 操作符,而确定一个值是哪种引用类型可以使用instanceof 操作符。
2.Undefined类型和Null类型
Undefined 类型只有一个值,即特殊的undefined。在使用var 声明变量但未对其加以初始化时,这个变量的值就是undefined,例如:
var message;
alert(message == undefined); //true
直接使用一个未声明的变量将会报错。对于尚未声明过的变量,只能执行一项操作,即使用typeof 操作符检测其数据类型。但是,而对未声明的变量执行typeof 操作符同样也会返回undefined 值。例如:
var message; // 这个变量声明之后默认取得了undefined 值
// 下面这个变量并没有声明
alert(null == undefined); //true
// var agealert(message); // "undefined"alert(age); // 产生错误alert(typeof message); // "undefined"alert(typeof age); // "undefined"
Null 类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用typeof 操作符检测null 值时会返回"object"的原因,例如:
var car = null;
alert(typeof car); // "object"
undefined 值是派生自null 值的,因此ECMA-262 规定对它们的相等性测试要返回true,即:
alert(null == undefined); //true
注意:如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null 而不是其他值。这样一来,只要直接检查null 值就可以知道相应的变量是否已经保存了一个对象的引用。这样做不仅可以体现null 作为空对象指针的惯例,而且也有助于进一步区分null 和undefined。
3. 判断null、undefined与NaN的方法
1、判断undefined:
var tmp = undefined;
if (typeof(tmp) == "undefined"){
alert("undefined");
}
说明:typeof
返回的是字符串,有六种可能:
"number"
、
"string"
、
"boolean"
、
"object"
、
"function"
、
"undefined"
2、判断null:
var tmp = null;
if (!tmp && typeof(tmp)!="undefined" && tmp!=0){
alert("null");
}
3
、
判断NaN:
var tmp = 0/0;
if(isNaN(tmp)){
alert("NaN");
}
4
、
判断undefined
和
null:
说明:如果把 NaN
与任何值(包括其自身)相比得到的结果均是
false
,所以要判断某个值是否是
NaN
,不能使用
==
或
===
运算符。
isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字。当然也可以用 isNaN() 函数来检测算数错误,比如用 0 作除数的情况。
var tmp = undefined;
if (tmp== undefined)
{
alert("null or undefined");
}
var tmp = undefined;
if (tmp== null)
{
alert("null or undefined");
}
说明:null==undefined
5.判断undefined、null与NaN:
var tmp = null;
if (!tmp)
{
alert("null or undefined or NaN");
}
提示:一般不那么区分就使用这个足够。
4. 基本包装类型
4.1 基本包装类型与基本类型
ECMAScript 还提供了3 个特殊的引用类型:Boolean、Number 和String。实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。来看下面的例子。
var s1 = "some text";
var s2 = s1.substring(2);
这个例子中的变量s1 包含一个字符串,字符串当然是基本类型值。而下一行调用了s1 的substring()方法,并将返回的结果保存在了s2 中。我们知道,基本类型值不是对象,因而从逻辑上讲它们不应该有方法(尽管如我们所愿,它们确实有方法)。其实,为了让我们实现这种直观的操作,后台已经自动完成了一系列的处理。
4.2、基本包装类型与引用类型
引用类型与基本包装类型的主要区别就是对象的生存期。使用new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。例如:
var s1 = "some text";
s1.color = "red";
alert(s1.color); //undefined
要注意的是,使用new 调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。例如:
var value = "25";
var number = Number(value); //转型函数
alert(typeof number); //"number"
var obj = new Number(value); //构造函数
alert(typeof obj); //"object"
在这个例子中,变量number 中保存的是基本类型的值25,而变量obj 中保存的是Number 的实例。
5. Global对象
全局对象(Global对象)是预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。全局对象不是任何对象的属性,所以它没有名称。
在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。但通常不必用这种方式引用全局对象,因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的 parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript 代码中声明的所有变量都将成为全局对象的属性。
注意:全局对象只是一个对象,而不是类。既没有构造函数,也无法实例化一个新的全局对象。
在 JavaScript 代码嵌入一个特殊环境中时,全局对象通常具有环境特定的属性。实际上,ECMAScript 标准没有规定全局对象的类型,JavaScript 的实现或嵌入的 JavaScript 都可以把任意类型的对象作为全局对象,只要该对象定义了这里列出的基本属性和函数。例如,在允许通过 LiveConnect 或相关的技术来脚本化 Java 的 JavaScript 实现中,全局对象被赋予了这里列出的 java 和 Package 属性以及 getClass() 方法。而在客户端 JavaScript 中,全局对象就是 Window 对象,表示允许 JavaScript 代码的 Web 浏览器窗口。
6. 类型总览图
1、本地对象(原生对象)
ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript实现提供的对象”。简单来说,本地对象就是 ECMA-262 定义的类(引用类型),它们包括:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。
2、内置对象
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。
注意:内置对象与原生对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集;而后者包括了一些在运行过程中动态创建的对象。
3、宿主对象
所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。