JavaScript数据类型以及类型判断

 


数据类型

  • 基本数据类型:Number、String、Boolean、Null、undefined,ES6新增了BigInt、Symbol
  • 引用数据类型:Object、Function

两种数据类型的区别

  基本数据类型是存储在栈中的;而引用数据类型是存储在堆中的,它会在栈中存储一个指向内容所在堆空间中的地址。

为什么要有两种数据类型?

  基本数据类型是直接存储值的,是存储内容本身;而引用数据类型存储的是内容的地址,指向内容本身。假设数据在多个地方被使用,如果该数据使用基本数据类型存储,那么这些地方拿到的都是该数据的新副本,它们之间是相互独立的,修改源数据也不会引起这些地方的更新。而使用引用数据类型存储,那么这些地方拿到的只是该数据的地址,当修改数据内容时,其它使用了该数据的地方就能拿到更新后的数据。

null与undefined的区别

  • undefined:表示未定义,是变量最原始的状态。当一个变量被声明了但还未赋值时,它的默认值是undefined;
  • null:表示空值,变量是有赋值的但赋值为空。比如,当一个变量被赋值为某个对象时,该变量存储的是这个对象的地址值,此时把变量赋值为null,相当于切断变量与对象的联系,变量指向的是空对象。

 非构造函数形式调用

  在非构造函数上下文中(没有new),Number、String、Boolean可被用来执行类型转换。但非构造函数形式与构造函数形式创建的不是同一个对象。

let s1 = '123';
let s2 = String(123);
let s3 = new String(123);
console.log(s1===s2);  //true
console.log(s2===s3); //false

 

数据类型的检测方法

typeof操作符

  

类型

输出结果

Undefined

“undefined”

Null

“object”

Boolean

“boolean”

Number

“number”

String

“string”

Function

“function”

BigInt

“bigint”

Symbol

“symbol”

其他任何对象

“object”

 

注意事项:

  • 使用typeof操作符检测数组类型时输出的是"object";
  • 除了new Function()之外,其他所有使用构造函数(new操作符)创建的变量用typeof检测类型输出都是"object";

 

let arr = [];
console.log(typeof arr);  //“object”

let str1 = new String(" ");
let str2 = " ";
console.log(typeof str1); //“object”
console.log(typeof str2); //"string" 

instanceof操作符

  语法:object instanceof constructor

  用于检测构造函数constructor的prototype属性是否出现在某个实例对象object的原型链上。

复制代码
let arr = [];
let str1 = "";
let str2 = String("");
let str3 = new String("");
console.log(arr instanceof Array); //true
console.log(str1 instanceof String); //false
console.log(str2 instanceof String); //false
console.log(str3 instanceof String); //true
console.log(1 instanceof Number); //false
console.log(new Number(1) instanceof Number); //true
复制代码

Object.prototype.constructor属性

  返回创建的实例对象的构造函数的引用,该属性的值是对构造函数本身的引用,也就是说,若输出某对象实例的constructor属性,输出的是构造函数代码,而不是包含构造函数名的字符串。

  

复制代码
let arr = [];
let str1 = "";
let str2 = String("");
let str3 = new String("");
console.log(arr.constructor === Array); //true
console.log(str1.constructor === String); //true
console.log(str2.constructor === String); //true
console.log(str3.constructor === String); //true
console.log((1).constructor === Number); //true
console.log((true).constructor === Boolean); //true
复制代码

 

注意事项

  • null、undefined类型的原始值是没有constructor属性的;
  • 对于自定义类,若重写该类的原型属性,有可能会导致该类的constructor不再指向该类的构造函数;

  类的组合继承方式中,重写子类的原型(SubType.prototype = new SuperType();)会导致子类的constructor属性不再指向子类构造函数。

 

console.log(instance1.constructor === SubType); //false
console.log(instance1.constructor === SuperType); //true 

 

Object.prototype.toString方法

  每个对象都有toString()方法,当该对象被表示为一个文本值或以预期的字符串方式引用时,都会自动调用该方法。默认情况下,若此方法在自定义类中没有被覆盖,toString()返回["object type"],其中type是对象的类型。

  由于非自定义对象(如Array、String等)已经重写了toString()方法,因此要实现数据类型检测功能,应该利用Function.prototype.call()方法来调用原始的Object.prototype.toString(),使其输出[object type],而我们只需要使用slice()方法取字符串的第8位到倒数第二位,即可提取出表示数据类型的字符串type。例如,下面检测字符串类型String:

 

let str = "";
console.log(Object.prototype.toString.call(str).slice(8,-1)); //String

 

相等(==)与严格相等(===)

相等操作符(==)与(!=)

相等运算符(==!=)使用抽象相等比较法比较两个操作数:

  • 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true
  • 如果一个操作数是null,另一个操作数是undefined,则返回true
  • 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
    • 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
    • 如果操作数之一是Boolean,则将布尔操作数转换为1或0。
      • 如果是true,则转换为1
      • 如果是 false,则转换为0
    • 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()toString()方法将对象转换为原始值。
  • 如果操作数具有相同的类型,则将它们进行如下比较:
    • Stringtrue仅当两个操作数具有相同顺序的相同字符时才返回。
    • Numbertrue仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false
    • Booleantrue仅当操作数为两个true或两个false时才返回true
复制代码
console.log("1" ==  1); // true
console.log(0 == false);  // true
console.log(0 == null);  // false
console.log(0 == undefined); // false
console.log(null == undefined); // true

const number1 = new Number(3);
const number2 = new Number(3);
console.log(number1 == 3);         // true
console.log(number1 == number2);   // false,因为是两个不同的实例
复制代码

 

全等操作符(===)与(!==)

 

全等运算符(===和 !==)使用全等比较法来比较两个操作数:
  • 如果操作数的类型不同,则返回 false
  • 如果两个操作数都是对象,只有当它们指向同一个对象时才返回 true
  • 如果两个操作数都为 null,或者两个操作数都为 undefined,返回 true
  • 如果两个操作数有任意一个为 NaN,返回 false
  • 否则,比较两个操作数的值:
    • 数字类型必须拥有相同的数值。+0 和 -0 会被认为是相同的值。
    • 字符串类型必须拥有相同顺序的相同字符。
    • 布尔运算符必须同时为 true 或同时为 false
复制代码
console.log("3" === 3);           // false
console.log(true === 1);          // false
console.log(null === undefined);  // false
const object1 = {
    name: "hello"
}
const object2 = {
    name:"hello"
}
const object3 = object1;
console.log(object1 === object2);  // false
console.log(object1 === object3); //true
复制代码

 

区别

  如果操作数的类型不同,== 运算符会在比较之前尝试将它们转换为相同的类型;而严格等于运算符不尝试类型转换,始终将不同类型的操作数视为不同。

 

关于NaN

  NaN(Not a Number),表示不是一个数字。它不管与谁比较都返回false,即使是(NaN == NaN)结果也为false。通常,我们使用isNaN()或Number.isNaN()方法来判断一个值是否为NaN。其中,

  • isNaN()在判断前会尝试将当前值强制转换为Number再进行判断;
  • Number.isNaN()仅当值为NaN时才返回true。

 

手写实现isNaN()

  利用NaN的“自身永不等于自身”这一特性来实现

 

var isNaN = function(value) {
    var n = Number(value);
    return n !== n;
};

 

posted @   ˙鲨鱼辣椒ゝ  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示