Javascritp 数据类型及其类型检测 基本类型和引用类型

249 1 年前
Javascript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。当一个变量赋值为一种类型的值后,可以再赋值为别的类型的值,虽然我们不建议修改变量所保存值的类型,但这种操作在 Javascriptcript 中是完全有效

Javascritp 中数据类型有七种,其实简单数据类型(基本数据类型)有六种:字符串、数字、布尔、Null、Undefined以及 ES6 引入了一种新的原始数据类型 Symbol,还有 1种复杂数据类型——Object。Javascript 不支持创建自定义类型。

基本数据类型

JavaScript 中共有 6 种基本数据类型:Undefined、Null、Boolean、Number、String、Symbol (ES 6引及)。

Undefined类型

表示变量不含有值 Undefined 类型只有一个值,即特殊的 undefined

声明未初始化的变量会自动被赋予 undefined 值与未定义的变量有点本质的区别

var message; // 声明之后默认为undefined 值
// 下面这个变量并没有声明
// var age
alert(message); // "undefined"
alert(age); // 产生错误

对未初始化的变量执行 typeof 操作符会返回 undefined 值,而对未声明 的变量执行 typeof 操作符同样也会返回 undefined 值。

var message; // 声明之后默认取得了 undefined 值
// 下面这个变量并没有声明
// var age
alert(typeof message); // "undefined"
alert(typeof age); // "undefined"

undefined 一般出现在以下几种情况: 1、在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined 2、获取不存在的属性名返回 undefined 3、在严格模式下,没有明确的执行主体,thisundefined 4、执行函数形参未传值,默认是 undefined 5、函数没有返回值(return或者return后面什么也不带),默认返回 undefined 6、在数组的find方法中,没有找到的情况下是 undefined

null类型

表示空对象指针,空,没有 Null 类型是第二个只有一个值的数据类型(第一个就是Undefined),这个特殊的值是 null

var car = null;
alert(typeof car); // "object"

如果定义的变量准备在后面保存对象,那么最好将该变量初始化为 null 而不是其他值。

null 一般出现在以下几种情况: 1、手动设置变量的值或者对象某一个属性值为null(此时不赋值,会在后面的代码中进行赋值,相当于初始化。) 2、在JS的DOM元素获取中,如果没有获取到指定的元素对象,结果一般是null。 3、Object.prototype._proto_的值也是null。 4、在正则捕获的时候,如果没有捕获到结果,默认也是null。

Boolean类型

该类型只有两个字面值:true 和 false。

var found = true;
var lost = false;

Boolean 类型的字面值 true 和 false 是区分大小写的。也就是说,True 和 False(以及其他的混合大小写形式)都不是 Boolean 值,只是标识符

Number类型

使用 IEEE754 格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。 JavaScript内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数。

Javascript 中有几种不同的数值字面量格式

  • 十进制:没有前导0的数值。
  • 八进制:有前缀0o或0O的数值(ES5 开始,在严格模式下八进制不再允许使用前缀0表示)。
  • 十六进制:有前缀0x或0X的数值。
  • 二进制:有前缀0b或0B的数值。

八进制字面量使用0在严格模式下是无效的,会导致引擎抛出错误。

var intNum = 55; // 整数
var octalNum1 = 070; // 八进制的 56
var octalNum2 = 079; // 无效的八进制数值——解析为 79
var octalNum3 = 08; // 无效的八进制数值——解析为 8
var hexNum1 = 0xA; // 十六进制的 10
var hexNum2 = 0x1f; // 十六进制的 31

在进行数学算术计算是,不同进制都被转换为十进制数值。 NaN是JavaScript的 特殊值,表示“非数字”(Not a Number),是一个特殊的数值 有 3 个函数可以把非数值转换为数值:Number()parseInt()parseFloat()

String类型

String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串。字符串可以由双 引号(")或单引号(')表示

var firstName = "Nicholas";
var lastName = 'Zakas';

引用数据类型

除过基本数据类型外,剩下的就是引用类型了,统称为 Object 类型。细分的话,有:Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型 等。 Javascript 对象其实就是一组数据和功能的集合 通过执行 new 操作符后跟构造函数的名称来创建该类型的对象实例。

JavaScript 对象是属性和方法的集合。 方法是作为对象成员的函数。属性是作为对象成员的一个值或一组值(以数组或对象的形式)。

JavaScript 支持四种对象:

  • 内部对象(如 Array 和 String)。
  • 创建的对象。
  • 宿主对象(如 window 和 document)。
  • ActiveX 对象。

每个对象实例都具有下列属性和方法:

  • constructor:指向创建当前对象的构造函数。
  • hasOwnProperty(propertyName):检查是否有指定的属性(不是在原型中)。
  • propertyIsEnumerable(propertyName):检查给定的属性是否能枚举。
  • toLocaleString():返回对象在执行环境的地区的字符串。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象的字符串、数值或布尔值表示。

引用数据类型太多了,一篇文章写不完,算了,后面再分开记录吧

typeof操作符 检测类型

首先要知道 typeof 是操作符,不是函数。

类型 结果
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol(ECMAScript 6 新增) "symbol"
宿主对象(由JS环境提供) Implementation-dependent
函数对象([[Call]] 在ECMA-262条款中实现了) "function"
任何其他对象 "object"

所以用 typeof 操作符是不能准确判断一个变量类型的,null的结果为 object , Array 的结果是 object,如何得到变量准确的数据类型呢?查看 jQery 源码,在其中用到的方法如下:

Object.prototype.toString.call(变量)
Object.prototype.toString.call("jerry");//[object String]
Object.prototype.toString.call(12);//[object Number]
Object.prototype.toString.call(true);//[object Boolean]
Object.prototype.toString.call(undefined);//[object Undefined]
Object.prototype.toString.call(null);//[object Null]
Object.prototype.toString.call(Symbol('a'));//[object Symbol]
Object.prototype.toString.call({name: "jerry"});//[object Object]
Object.prototype.toString.call(function(){});//[object Function]
Object.prototype.toString.call(function* (){});//[object GeneratorFunction]
Object.prototype.toString.call(Promise.resolve());//[object Promise]
Object.prototype.toString.call([]);//[object Array]
Object.prototype.toString.call(new Date);//[object Date]
Object.prototype.toString.call(/\d/);//[object RegExp]
function Person(){};
Object.prototype.toString.call(new Person);//[object Object]
var obj = Object.create( null );
Object.prototype.toString.call(obj);//"[object Object]"
Object.getPrototypeOf(obj)//null

检测数据类型

var class2type = {};
  "Boolean Number String Function Array Date RegExp Object Error Symbol".split(" ").forEach(function(name,i,arr){
    class2type["[object " + name + "]"] = name.toLowerCase();
  })
  function toType( obj ) {
    if ( obj == null ) {
      return obj + "";
    }
    return typeof obj === "object" || typeof obj === "function" ? class2type[ {}.toString.call( obj ) ] || "object" : typeof obj;
  }

其实,在ES2015后通过Object.prototype.toString获取数据类型己经不可靠,因为可以通过对象的Symbol.toStringTag属性可以修改Object.prototype.toString方法返回的类型"[object xxxxx]"

instanceof运算符 检测类型

用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置,简单说就是判断一个引用类型的变量具体是不是某种类型的对象(实例)

({}) instanceof Object              // true
([]) instanceof Array               // true
(/aa/g) instanceof RegExp           // true
(function(){}) instanceof Function  // true
分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6