js的八大数据类型以及四种检测方法

js数据类型

js的数据类型一共存在8种。

  • 在es5中存在6种数据类型 undefined String Object Number Null Boolean
  • ES6新增了一种数据类型 Symbol :这种类型的对象永不相等,即便创建的时候传入相同的值也不相等
    主要用于解决属性名冲突问题
  • 谷歌也出现了一种bigInt,指的是安全存储,操作大整数
  • 所以js数据类型包含了以上八种 undefined String Object Number Null Boolean Symbol bigInt

当然可以这样来进行简记 USONB 这样会不会记得更加牢固了呢?

Object包含了哪几种类型?
最常用的就是Array function Data

js的数据类型分为基本类型和引用类型

  • 基本数据类型指的是简单的数据段
  • 引用数据类型指的是有多个值构成的对象

基本类型: String、Number、boolean、null、undefined

  • 这五种基本类型可以直接访问,他们是按照值进行分配的,存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配

引用类型:Object 。里面包含function array data

  • 引用类型即存放在堆内存中的对象,变量实际保存的是一共指针,这个指针指向另一个位置

null和undefined区别

  • null 只有一个值,是null,不存在的对象,表示一个空对象指针
  • undefined只有一个值,是undefined。没有初始化。undefined是从null中派生出来的
  • 简单理解就是:undefined是没有定义的,null是定义了但是为空!

检测数据类型的方法:

1. typeof

typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。
返回的结果用该类型的字符串(全小写字母)形式表示
包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等。

			//1 typeof
			console.log(typeof "");
			console.log(typeof 1);
			console.log(typeof true);
			console.log(typeof null);
			console.log(typeof undefined);
			console.log(typeof []);
			console.log(typeof function(){});
			console.log(typeof {});
			console.log(typeof Symbol());  //symbol

结果:
js的八大数据类型以及四种检测方法_第1张图片

从上述结果中可以看到,typeof对于基本数据类型的判断是没有问题的,但是遇到了引用数据类型
是不起作用的,只能返回一个object。(typeof(null)输出object 是因为在js中,null表示一个空对象指针)

  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于 null ,返回 object 类型。
  • 对于 function 返回 function 类型。

2、instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
在这里需要特别注意的是:instanceof 检测的是原型,我们用一段伪代码来模拟其内部执行过程:

			instanceof (A,B) = {
			    var L = A.__proto__;
			    var R = B.prototype;
			    if(L === R) {
			        // A的内部属性 __proto__ 指向 B 的原型对象
			        return true;
			    }
			    return false;
			}

从上述过程可以看出,当 A 的 proto 指向 B 的 prototype 时,就认为 A 就是 B 的实例
我们来看几个例子

//instanceof
			console.log([] instanceof Array) // true
			console.log({} instanceof Object) // true
			console.log(new Date() instanceof Date) //true
			
			function Person(){};
			console.log(new Person() instanceof Person)  //true
			console.log([] instanceof Object)          //true
			console.log(new Date() instanceof Object)   //true
			console.log(new Person instanceof Object)   //true
			console.log("1" instanceof String);    //false
			console.log(1 instanceof Number);     //false
			console.log(true instanceof Boolean);   //false

由此可见对于基本数据类型是无效的!
其中值得注意的是:
console.log([] instanceof Array) // true
console.log([] instanceof Object) //true
那么为什么会这样呢?三者之间存在什么关系呢?

  • 从 instanceof 能够判断出 [ ].proto 指向 Array.prototype,
  • 而 Array.prototype.proto 又指向了Object.prototype,
  • 最终 Object.prototype.proto 指向了null,标志着原型链的结束。
  • 因此,[]、Array、Object 就在内部形成了一条原型链:
    js的八大数据类型以及四种检测方法_第2张图片

从原型链可以看出,[] 的 proto 直接指向Array.prototype,
间接指向 Object.prototype,所以按照 instanceof 的判断规则,[] 就是Object的实例。
依次类推,类似的 new Date()、new Person() 也会形成一条对应的原型链 。
因此,instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。

3、constructor

当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用。如下所示:
js的八大数据类型以及四种检测方法_第3张图片

当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时 F 原型上的 constructor 传递到了 f 上,因此 f.constructor == F
js的八大数据类型以及四种检测方法_第4张图片

可以看出,F 利用原型对象上的 constructor 引用了自身,当 F 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型。
同样,JavaScript 中的内置对象在内部构建时也是这样做的:

js的八大数据类型以及四种检测方法_第5张图片
注意:

  1. null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
  1. 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

js的八大数据类型以及四种检测方法_第6张图片

为什么变成了 Object?

因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
因此,在重写对象原型时一般都需要重新给constructor赋值,以保证对象实例的类型不被篡改

4、Object.prototype.toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

		<script type="text/javascript">
			var a = Object.prototype.toString;
			
			console.log(a.call("aaa"));
			console.log(a.call(1));
			console.log(a.call(true));
			console.log(a.call(null));
			console.log(a.call(undefined));
			console.log(a.call([]));
			console.log(a.call(function() {}));
			console.log(a.call({}))
			console.log({}.toString());
		</script>

结果:
js的八大数据类型以及四种检测方法_第7张图片

可以看到,所有的数据类型,这个办法都可以判断出来
那或许会有人会质疑,假如我改变一下它的原型呢?还能正确判断吗?
那我们测试一下
在这里插入图片描述

那这里就可以放心了吧,仍然可以得到正确的结果!

你可能感兴趣的:(javascript学习之路,js,数据类型,constructor,前端,toString)