每一种计算机语言都有自己所支持的数据类型。 JavaScript 脚本语言中采用的是弱类型的方式,即一个数据(变量或常量)不必首先做声明,可在使用或赋值时才确定其数据的类型。当然也可以先声明该数据的类型,即通过在赋值时自动说明其数据类型。
在 JavaScript 中,基本数据类型变量分配在栈内存中,其中存放了变量的值,对其是按值来访问的;而对象类型的变量则同时会分配栈内存和堆内存,其中栈内存存放的是地址。堆内存存放的是引用类型的值,栈内存存放的地址指向堆内存中存放的值。对该变量的访问是按引用来访问的,即首先读取到栈内存存放的地址,然后按该地址找到堆内存读取其中存放的值。
JavaScript 之所以按变量的不同数据类型来分配内存,主要原因是栈内存比堆内存小,而且栈内存的大小是固定的,而堆内存大小可以动态变化。基本数据类型的值的大小固定,对象类型
仅包含两个固定值 true 和 false 。
还有另外一种使用方式: JavaScript 把非 0 值当作 true 来处理,把 0 值当作 false 来处理。下面这些值在 JavaScript 里都当作 false 处理:
!!'demo'; //true
!!''; // false
!!'0'; //true
!!'1'; //true
!!{}; //true
!!true; //true
使用 " ! "操作符两次,可以把一个值转换为布尔型。
constructor 属性用于对当前对象的函数的引用。
prototype 属性可以对对象添加属性和方法。
toString 方法。
该方法用于将 Boolean 值转换成字符串 BooleanObject.toString() 。
valueOf 方法用于返回 Boolean 对象的原始值 BooleanObject.valueOf() 。
快速检测出初始化。
var b;
b = b ? b : 'OK ';
alert(b);
Null 类型的数据只有一个值,那就是 null 。逻辑上讲, null 值表示一个空对象指针,这也是给 typeof 传一个 null 会返回 "object " 的原因。
当一个变量值为 null 时, JavaScript 会自动回收它,已避免占用无效空间。
undefined 值是由 null 值派生而来的,因此 ECMA-262 将它们定义为表面上相等
原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判 断为 object 类型, null 的二进制表示是全 0 ,自然前三位也是 0 ,所以执行 typeof 时会返回 " object "。
null 是 JavaScript 的关键字,表示没有对象,用于定义空的或不存在的引用。 null 参与算术运算时其值会自动转换为0
undefined 是 Undefined 类型的唯一值,表示未定义的值。当声明变量未赋值时,或者定义属性未设置值时,默认它们的值为 undefined 。
null 和 undefined 都是假值,可以相等:
alert(null == undefined); // 返回 true
但是, null 和 undefined 是不同类型的数据,使用全等运算符( === )或 typeof 运算符可以区分检测。
alert(null === undefined); // 返回 false
alert(typeof null); // 返回 'object'
alert(typeof undefined); // 返回 'undefined'
undefined 参与算术运算时转换为 NaN ( Not a Number ,即不是一个数字,属于数字类型)
检测一个变量是否被初始化,可以借助 undefined 值进行快速检测。
var a;
alert(a);
a == undefined && (a = 0);
alert(a);
也可以用 typeof 运算符检测变量是否初始化。
typeof a == 'undefined' && (a = 0);
当声明了 a ,却没有声明 b 时,然后用 typeof 运算符检测它们的类型,返回的值都是字符串 "undefined" 。
var a;
alert(typeof a); // 返回 undefined
alert(typeof b); // 返回 undefined
对于未声明的变量 b 来说,如果直接在表达式中使用,会引发异常。
// 提示未定义的错误信息;
alert(b == undefined);
对于函数来说,如果没有明确的返回值则默认返回值都为 undefined 。
function f() {}
alert(f());
与 null 不同的是, undefined 还不是 JavaScript 的保留字,在 ECMAScript v3 标准中才定义 undefined 为全局变量,初始值为 undefined 。因此,在使用 undefined 时,应注意早期的浏览器可能不支持。
let str = '';
str += '';
str += '(typeof \"a"\) ---->**_' + type('a') + '_**';
str += '(typeof 1) ---->**_' + type(1) + '_**';
str += '(typeof true) ---->**_' + type(true) + '_**';
str += '(typeof {}) ---->**_' + type({}) + '_**';
str += '(typeof []) ---->**_' + type([]) + '_**';
str += '(typeof function(){}) ---->**_' + type(function () {}) + '_**';
str += '(typeof undefined) ---->**_' + type(undefined) + '_**';
str +=
'(typeof null) ---->**_' +
type(null) +
'_**<small>已对 typeof 函数进行处理 </small>';
str += '(typeof NaN) ---->**_' + type(NaN) + '_**';
str += '';
document.querySelector('#node_123').innerHTML = str;
由于 null 值返回类型为 object ,可以定义一个检测简单数据类型的一般方法。
function type(o) {
return o === null ? 'null' : typeof o;
}
constructor 是 Object 类型的原型,它能够返回当前对象的构造器(类型函数)。
var o = {};
var a = [];
alert(o.constructor == Object); // 返回 true
alert(a.constructor == Array); // 返回 true
值 | typeof value | value.constructor |
---|---|---|
var value = 1 | "number" | Number |
var value = "a" | "string" | String |
var value = true | "boolean" | Boolean |
var value = {} | "object" | Object |
var value = new Object() | "object" | Object |
var value = [] | "object" | Array |
var value = newArray() | "object" | Array |
var value = function(){} | "function" | Function |
function className(){}; var value = new className(); | "object" | className |
对于 null 、 undefined ,不能够使用 constructor ,且数值直接量也无法使用。如果结合 typeof 运算符 和 constructor 属性,基本上可以确定数据的类型的检测。
使用 toString() 方法可以设计一种更安全的检测 JavaScript 数据类型的方法。
由 Object 对象定义的 toString() 方法返回的字符串总是。
[object class]
其中 object 表示对象的通用类型, class 表示内部类型,内部类型总与该对象的构造函数名对应。例如: Array 对象的 class 为 "Array" ; Function 对象的 class 为 "Function" ; Date 对象的 class 为 "Date" ;内部 MAth 对象的 class 为 "Math" ;所有 Error 对象的 class 为 "Error" 。
客户端的 JavaScript 的对象和由 JavaScript 实现定义的其它所有对象都具有特定的 class 值,如 "window" 、 "Document" 和 "Form" 等。我们自定义的对象的 class 为 "Object" 。
class 值提供的信息与对象的 constructor 属性值相似 , 但是 class 值是以字符串的形式提供这些信息 , 者在特定的环境下非常有用。如果使用 typeof 运算符来检测,则所有的对象的 class 值都为 "Object" 或 "Function" 。即不能提供有效信息。
但是,要获取对象的 class 值唯一的方法是必须调用 Object 的原型方法 toString() ,因为许多对象都会重置 Object 的 toString() 方法,所以不能直接用对象的 toString ()方法。
调用 Object 的 toString() 原型方法,可以通过调用 Object.prototype.toString() 对象的默认 toString() 函数,再调用该函数的 apply() 方法在想要检测的对象上执行即可。
// 安全检测 Javascript 基本数据类型 和 内置对象
// 参数: o 表示检查值
// 返回的值:返回字符串 "undefined" 、 "number" 、 "boolean" 、
// "string" 、 "function" 、 "regexp" 、 "array" 、
// "date" 、 "error" 、 "object" 、 "null"
function typeOf(o) {
// 获取对象的 toString() 方法的调用 // 列举基本数据类型 和 内置对象类型
var l_toString = Object.prototype.toString;
var l_type = {
undefined: 'undefined',
number: 'number',
boolean: 'boolean',
string: 'string',
'[object Function]': 'function',
'[object RegExp]': 'regexp',
'[object Array]': 'array',
'[object Date]': 'date',
'[object Error]': 'error',
};
return (
l_type[typeof o] || l_type[l_toString.call(o)] || (o ? 'object' : 'null')
);
// 通过把值转换成字符串,然后匹配返回字符串中是否含有特定的字符进行检测
}
上述方法仅适用于 JavaScript 基本数据类型和内置对象,但是对于自定义对象是无效的。因为自定义对象被转换为字符串后,返回的值没有规律,且不同的浏览器返回的值也不相同。因此,检测非内置对象,只能使用 constructor 属性和 instanceof 运算符来实现。
BigInt 是在 2019年 9月被正式纳入 ECMAScript 标准中的特性。虽然 BigInt 不是频繁使用的特性,但其特殊性在于它是一种新的原始数据类型,同时又属于数值类型的一种。由于 BigInt 类型的加入, JavaScript 中共支持两种数值类型,即 Number 类型和 BigInt 类型。
BigInt 字面量的语法是在一个整数后面添加一个小写字母“ n ”。字母“ n ”必须紧随数字之后,两者之间不允许存在空白字符。
使用 BigInt()函数也能够创建 BigInt 类型的值。 BigInt()函数会尝试将传入的参数转换为 BigInt ,最基本的使用场景是将一个整数转换为 BigInt 类型的值。
BigInt 类型的值能够与 Number 类型的值进行大小及相等关系的比较。在进行严格相等比较时, BigInt 类型的值与 Number 类型的值永远不相等。在进行非严格相等比较及大小关系比较时, BigInt 类型的值与 Number 类型的值将进行数学意义上的比较。
虽然 BigInt 类型的值可以与 Number 类型的值进行比较,但是 BigInt 类型的值不允许与 Number 类型的值一起进行混合数学运算。
通过内置的 Number()函数能够将 BigInt 类型的值转换为 Number 类型的值。但要注意,在 BigInt 类型与 Number 类型之间进行强制类型转换时有可能损失精度。