前言
学习一门语言,当然要从数据类型开始。正确判断数据类型是我们写好程序的第一步。
结合之前所学的一些知识,对数据类型进行了总结。
如有错误,还望指正。
分类
基本(值)类型
- String:任意字符串
- Number:任意的数字
- boolean:true / false
- undefined:undefined
- null:null
- bigInt:可以用任意精度表示整数
- symbol:符号类型是唯一的并且是不可修改的,通常用来作为object的key
引用(对象)类型
- Object:任意对象
- Function:一种特别的对象(可以执行)
- Array:一种特别的对象(数值下标,内部数据是有序的)
如何判断数据类型
三种方法:
typeof
typeof返回数据类型的字符串表达
注:可以判断undefined、数值、boolean、字符串,不能判断null与object object与array
instanceof
判断对象的具体类型
===
注:可以判断undefined,null
判断基本类型
var a
console.log(a,typeof a,typeof a === 'undefined',a === undefined) // undefined 'undefined' true true
console.log(undefined === 'undefined') // false
var a
a = 3
console.log(typeof a === 'number') // true
a = 'Ned'
console.log(typeof a === 'string') // true
a = true
console.log(typeof a === 'boolean') // true
a = null
console.log(typeof a, a=== null) // object
请注意:这里string,s一定要小写,否则会是false,这是因为人家已经设计好的,是固定的。
判断对象类型
var b1 = {
b2: [a,'abc',console.log]
b3: function (){
console.log('b3')
}
}
整体的 b1 是个对象,b2 是数组, b3 是函数。
console.log(b1 instanceof Object, b1 instanceof Array) // true false
console.log(b1.b2 instanceof Array, b1.b2 instanceof Object) // true true
console.log(b1.b3 instanceof Function, b1.b3 instanceof Object) // true true
标注一下 instance of 的用法[实例] instanceof [类]
如果这个实例是类的实例,就返回true,反之返回false
也就是说,我们判断对象类型,要用instanceof。
另:判断function
还可以用typeof
console.log(typeof b1.b3 === 'function' // true
不知道大家有没有注意,b2的第三个值我们写了个console.log,下面我们也来判断一下它,应该是个function的。
console.log(typeof b1.b2[2] === 'function') // true
所以我们要调用这个函数的时候可以直接b1.b2[2]()
,这里提醒大家,我们千万不要被b1.b2[2]
所迷惑,我们要清楚它的数据类型到底是什么。
就此情况,我们上面b1中的b3改写一下。
var b1 = {
b3: function (){
console.log(b3)
return function (){
return 'Ned'
}
}
}
我们想要得到'Ned'
,应该怎么做?
只需要调用这个返回过来的函数即可:b1.b3()()
,输出一下:
console.log(b1.b3()())
所以不要拘泥于表面现象,一定要看清楚得到的是什么类型的数据,才能进行下一步的操作!
补充
手写instanceof
想要手写,我们首要的就是要了解它的原理。
原理:验证当前类的原型prototype是否会出现在实例的原型链proto上,只要在它的原型链上,则结果都为true。因此,instanceof
在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype
,找到返回true,找不到返回false。
function myinstanceOf(left,right){
let proto = left.__proto__
let prototype = right.prototype
while(true){
if(proto == null){
return false
}
if(proto == prototype){
return true
}
proto = proto.__proto__
}
}
constructor(用于引用数据类型)
- 语法: 被检测数据.constructor === class
特点:
- 适合使用在引用数据类型上
- 原型链不会干扰
- 原理:构造函数原型上有一个 constructor 属性指向构造函数自身的,如果在实例上使用 construtor 时,就会直接使用其构造函数原型的上的该属性,并指向其构造函数。
Object.prototype.toString.call()(对象原型链判断方法)
- 语法:Object.prototype.toString.call(被检测数据)
- 特点:适用于所有类型的判断检测
- 原理:Object.prototype.toString 表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果
补充,相关问题
undefined与null的区别?
- undefined表示定义未赋值
- null表示定义并赋值了,只是值为null
var a
console.log(a) // undefined
a = null
console.log(a) // null
什么时候给变量赋值为null呢?
- 初始赋值,表明将要赋值为对象
- 结束前,让对象成为垃圾对象,被回收掉。
不知道大家是否还记得,typeof 一个null的时候,返回的是什么?
var a = null
console.log(typeof a) // object
没错,是object。
所以当我们将一个变量的初始值赋值为null的时候,我们是向其他程序员表明,这个变量将会被赋值为对象。
不这么做行不行? 当然可以。那为什么还要这么做?
当然是因为,编程也是很严谨的。
var b = null // 初始赋值为null,表明将要赋值为对象
b = ['Ned',20] // 确定对象就赋值
b = null // 最后,让b指向的对象成为垃圾对象(被垃圾回收器回收)
严格区别变量类型与数据类型
数据的类型
- 基本类型
- 对象类型
变量的类型(变量内存值的类型)
- 基本类型:保存就是基本类型的数据
- 引用类型:保存的是地址值
平时的时候我们不会去区分这个概念。
简单的了解到这个概念就行吧~。