面试拷问之“JS数据类型”

194 阅读5分钟

JavaScript 数据类型详解

在前端开发中,JavaScript 是一种不可或缺的语言。理解 JavaScript 的数据类型及其内存分配机制,对于编写高效、可靠的代码至关重要。本文将详细介绍 JavaScript 中的数据类型,包括简单数据类型和复杂数据类型,并探讨它们的内存分配机制、拷贝方式以及如何准确判断变量的类型。

JavaScript 数据类型概述

JavaScript 是一种动态类型语言,提供了多种数据类型来满足不同的编程需求。根据 ES6 的引入,JavaScript 数据类型可以分为七种或八种,具体如下:

56840799d55752bd23d7a26fb329d8b.png 这里的Number类型和Bigint类型可以归为Numeric一种类型。

内存分配机制

在 JavaScript 中,简单数据类型和复杂数据类型的内存分配机制是不同的。

  • 简单数据类型:存储在栈内存中,直接存储实际的值。 9d8add33a34c020d88067ccb03ad72ac.png
  • 复杂数据类型:存储在堆内存中,栈内存中存储的是指向堆内存的地址。 a8178647a94e269c5760d94d57b77486.png

拷贝方式

  • 简单数据类型:按值拷贝,即复制实际的值。
// 值拷贝
let a = 1;
let b = a;
b = 3;
console.log(a,b); // 1, 3
  • 复杂数据类型:按引用拷贝,即复制指向堆内存的地址。
// 对象字面量
let obj = {
    name:'obj',
    job:'前端开发工程师',
    company:'腾讯'
}
let obj2 = obj;
obj2.name = '染染';
console.log(obj,obj2);

image.png

简单数据类型(Primitive Types)

1. number

  • 表示数值,包括整数和浮点数。

  • 示例:

    let num = 123;
    let floatNum = 3.14;
    

2.ES6新增类型 bigint

JS是一门具有强大的表现力的语言,适合前端, 但是 不擅长计算,容易精度丢失。

示例:

//数子范围有限
let num1 = 999999999999999999999999999;
let num12 =123455474424316547664653536;
console.log(num1+num12); //计算结果不精确

image.png

  • 所以ES6推出了Bigint类型

    • 表示大整数,用于处理超过 Number.MAX_SAFE_INTEGER 的整数。

    • 示例:

    let bigNum = 999999999999999999999999999n;
    let anotherBigNum = 123455474424316547664653536n;
    console.log(bigNum + anotherBigNum); // 计算结果
    

image.png

3. string

  • 表示文本字符串。

  • 示例:

    let str = "Hello, World!";
    

4. boolean

  • 表示布尔值,只有 true 和 false 两种值。

  • 示例:

    let isTrue = true;
    let isFalse = false;
    

5. null

  • 表示一个空值或不存在的对象。

  • 示例:

     let a = null; // 栈内存
    console.log(a);
    // 堆内存 对象  
    let largeObject = {
        data:new Array(10000000000).fill('a'),
    }
    // 设计为null类型 释放内存
    largeObject = null;
    console.log(largeObject);
    
  • 用途:通常用于表示某个值尚未被赋值或已经释放的空间。

  • 内存回收:显式回收内存。

6. undefined

  • 表示一个未定义的值,通常用于声明但未赋值的变量。

  • 示例:

    let undeclared;
    console.log(undeclared); // 输出 undefined
    

7. symbol

  • 表示唯一的值,常用于对象属性的键。

  • 示例:

    let sym1 = Symbol('马斯克');
    let sym2 = Symbol('马斯克');
    console.log(sym1 === sym2); // 输出 false
    

image.png

复杂数据类型(Complex Types)

1. object

  • 表示复杂的数据结构,可以包含多个属性和方法。

  • 示例:

    let person = {
        name: "Alice",
        age: 25,
        greet: function() {
            console.log("Hello, " + this.name);
        }
    };
    person.greet(); // 输出 "Hello, Alice"
    

特殊的复杂数据类型

函数
  • 函数在 JavaScript 中是一种特殊的对象,称为函数对象。

  • 函数可以有属性和方法,可以作为参数传递,也可以作为返回值返回。

  • 示例:

    function greet(name) {
        console.log("Hello, " + name);
    }
    
    let greetingFunction = greet;
    greetingFunction("Bob"); // 输出 "Hello, Bob"
    
数组
  • 数组是一种特殊的对象,用于存储多个值。

  • 数组是可遍历和迭代的。

  • 示例:

    let numbers = [1, 2, 3, 4, 5];
    for (let num of numbers) {
        console.log(num);
    }
    
  • for...of 循环是 ES6 引入的一种新的循环结构,用于遍历可迭代对象(如数组、字符串、Map、Set 等)。

  • let num of numbers:这行代码表示每次循环时,将 numbers 数组中的一个元素赋值给变量 num

类型判断

typeof 操作符

  • typeof 操作符可以用来判断变量的类型,但对于 null 类型会返回 "object",这是 JavaScript 设计时的一个 bug。

  • 示例:

    console.log(typeof 123); // "number"
    console.log(typeof "hello"); // "string"
    console.log(typeof true); // "boolean"
    console.log(typeof null); // "object" (错误)
    console.log(typeof undefined); // "undefined"
    console.log(typeof Symbol('test')); // "symbol"
    console.log(typeof {}); // "object"
    console.log(typeof []); // "object"
    console.log(typeof function() {}); // "function"
    

instanceof 操作符

  • instanceof 操作符可以用来判断一个对象是否是某个构造函数的实例。

  • 示例:

    let arr = [];
    console.log(arr instanceof Array); // true
    console.log(arr instanceof Object); // true
    

Object.prototype.toString.call 方法

  • 使用 Object.prototype.toString.call 方法可以准确判断变量的类型。

  • 示例:

       console.log(Object.prototype.toString.call(123)); // "[object Number]"
       console.log(Object.prototype.toString.call("hello")); // "[object String]"
       console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
       console.log(Object.prototype.toString.call(null)); // "[object Null]"
       console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
       console.log(Object.prototype.toString.call(Symbol('test'))); // "[object Symbol]"
       console.log(Object.prototype.toString.call({})); // "[object Object]"
       console.log(Object.prototype.toString.call([])); // "[object Array]"
       console.log(Object.prototype.toString.call(function() {})); // "[object Function]"

总结

JavaScript 提供了丰富的数据类型,包括简单数据类型和复杂数据类型。了解这些数据类型的内存分配机制、拷贝方式以及如何准确判断变量的类型,对于编写高效、可靠的 JavaScript 代码至关重要。希望本文能帮助你更好地理解和使用 JavaScript 的数据类型。如果有更多问题或需要进一步的示例,请随时提问。

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏和分享!也欢迎关注我的其他技术文章,了解更多前端开发的知识和技巧。