数据类型的判断

JavaScript类型可以分为两类:原始类型和对象类型。原始类型包括数值、字符串、布尔值和两个特殊值nullundefined。除了上述值以外的值都是对象类型。对象是属性的集合,对象也有很多种,比如普通对象、数组、Set、Map、Date、function等等。

内存结构

程序运行时,计算机内存会为程序开辟出一块专用内存,用于存储数据。在JavaScript中,变量名和变量值都是数据,但是它们存储的位置是不同的,变量名存储在内存的一个空间中,变量值是存储在另一个空间中。

每一个值都有一个内存地址,变量名实际上保存的就是值的内存地址,这样就建立了名字和值的联系。

前面我们知道了值分为原始类型和对象类型,而内存分为栈内存与堆内存。

  • 栈内存用于保存变量名,内存地址和原始类型。
  • 堆内存用于保存对象类型。

内存中不会创建重复的原始类型,可以理解为原始类型是不可改变的。

ini 复制代码
let a = 'HelloWorld';
let b = 'HelloWorld';

但是内存中可以创建重复的对象类型,并且它们的内存地址不同。

  • 给不同变量赋值同样的原始类型,它们是相等的,它们保存的是同一个内存地址。
  • 给不同变量赋值同样的对象类型,它们是不相等的,因为它们比较的是内存地址。
ini 复制代码
let a = 1;
let b = 1;
console.log(a === b); // true
let arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false

对象中的属性和值是可修改的。

  • 变量arr1赋值给变量arr2,实际上是把arr1保存的数组[1, 2, 3, 4]的内存地址赋给arr2。它们俩指向同一个地址的数组,所以arr1修改对arr2是有影响的。
ini 复制代码
var arr1 = [1, 2, 3, 4];
var arr2 = arr1;
arr1.push(5);
// arr1和arr2的地址是同一个
console.log(arr1 + '|' + arr2); // 1,2,3,4,5|1,2,3,4,5
  • 重新赋值的过程是指向了新的内存地址。
ini 复制代码
var arr1 = [1, 2, 3, 4];
var arr2 = arr1;
arr1 = [1, 2];
console.log(arr1 + '|' + arr2);
// 1,2|1,2,3,4,5

类型判断

typeof

typeof(data)方法 返回一个字符串用于表示参数的数据类型,但是对于引用类型它只能区分是函数还是其它引用类型,比如以下代码中的对于数组的返回结果就是object

javascript 复制代码
console.log(typeof(123)); // "number"
console.log(typeof("hello")); // "string"
console.log(typeof(true)); // "boolean"
console.log(typeof(undefined)); // "undefined"
console.log(typeof(null)); // "object"
console.log(typeof({})); // "object"
console.log(typeof([])); // "object"
console.log(typeof(function(){})); // "function"
console.log(typeof(null)); // "object"
console.log(typeof(NaN)); // "number"
console.log(typeof(document.all)); // "undefined"

注意null是一个object类型,它最早是空对象的指针,目前来说是一个历史遗留问题。

csharp 复制代码
console.log(typeof(null)); //object

如果一个变量a未定义,使用typeof()返回的是undefined,注意这个undefined是字符串格式的。

csharp 复制代码
console.log(typeof(a)); // undefined
console.log(typeof(typeof(a))); // string

constructor

constructor 指向创建该实例对象的构造函数。

ini 复制代码
var arr = [];
console.log(arr.constructor); // ƒ Array() { [native code] }

instanceof

instanceOf()方法 判断一个对象是否是右边的实例。

javascript 复制代码
function Car(){}
var car = new Car();

console.log(car instanceof Car); // true

并且只要该对象能通过原型链访问到右边,都会返回true。

  • 第一条语句打印true,因为Car构造函数是由Function构造函数创建的实例。
  • 第二条语句打印fasle,因为car对象和Function之间并不存在原型链上的联系。
  • 第三条语句打印true,因为car对象可以找到Car构造函数的原型,然后接着找到Object
javascript 复制代码
function Car(){}
var car = new Car();

console.log(Car instanceof Function); // true
console.log(car instanceof Function); // false
console.log(car instanceof Object); // true

Object.prototype.toString

toString()方法 不接收参数,返回表示调用它的对象的值的字符串,注意的是它返回的字符串格式为[object 对象类型]

ini 复制代码
var obj = {name: 'Li'};
console.log(obj.toString()); // [object Object]

所以虽然默认的toString()方法不会显示太多信息,但是可以用于判断数据的类型,所以可以结合call使用。

对于 Object.prototype.toString.call(arg),若参数argnullundefined,直接返回结果。

javascript 复制代码
console.log(Object.prototype.toString.call(undefined)) // "[object Udefined]"
console.log(Object.prototype.toString.call(null)) // "[object Null]"

对于其他数据类型,如果是原始数据类型,那么首先是进行包装类,如果是引用对象类型则直接使用。

javascript 复制代码
console.log(Object.prototype.toString.call(123)) // "[object Number]"
console.log(Object.prototype.toString.call('HelloWorld')) // "[object String]"
console.log(Object.prototype.toString.call(true)) // "[object Boolean]"
console.log(Object.prototype.toString.call({name: 'Li'})) // "[object Object]"
console.log(Object.prototype.toString.call([1, 2, 3])) // "[object Array]"
console.log(Object.prototype.toString.call(function(){var a = 1;})) // "[object Function]"
  • 在实际项目中会经常使用这个方式判断数据类型,使用时要注意变量缓存。
ini 复制代码
var arr = [];

var str = Object.prototype.toString,
    trueTip = '[object Array]';
if(str.call(arr) === trueTip){
    console.log('是数组');
}else{
    console.log('不是数组');
}

由于这个默认方法不会显示太多有用的信息,所以很多类都会重新定义自己的toString()方法。比如,在把数组转换为字符串时,会得到数组元素的一个列表,每个元素都会转换为字符串。而把函数转换为字符串时,可以得到函数的源代码。

  • 原始类型重新定义的toString()方法,会返回当前值的字符串。
  • 注意undefinednull并没有自己的toString()方法,直接调用会报错。
ini 复制代码
var a = 'HelloWorld',
    b = 123,
    c = true,
    d = undefined,
    e = null,
    f = [4, 5, 6],
    g = function(){
         var str = 'demo';
    };
console.log(a.toString()); // 'HelloWorld'
console.log(b.toString()); // '123'
console.log(c.toString()); // 'true'
// console.log(d.toString()); // error
// console.log(e.toString()); // error
console.log(f.toString()); // '4, 5, 6'
console.log(g.toString()); // 'function(){ var str = 'demo'; }'
相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax