📘第一章:数据类型
✍️ 作者:桑榆
🕓 更新时间:2026-06-04
🧠 关键词:数据类型
第一章:数据类型
1.它是什么
JavaScript 的值,先大致分成两类:
- 基本类型
- 对象类型
基本类型 一共有 7 个:
- number
- string
- boolean
- undefined
- null
- symbol
- bigint
对象类型 广义上,除了基本类型,其他基本都可以看成对象:
- 普通对象 {}
- 数组 []
- 函数 function(){}
- 日期 new Date()
- 正则 /a/
- Map
- Set
你面试里最常说的一句就是:
JS 中数据类型分为基本类型和引用类型(对象类型
2. 为什么这样设计
因为 JavaScript 需要同时处理两类完全不同的数据:
第一类:简单值
比如:
- 1
- 'abc'
- true
它们很小,很简单,直接拿来算、拿来比较就行。
第二类:复杂值
比如:
const user = {
name: 'Tom',
age: 18
}这种值内部有多个字段,甚至字段里还能嵌套对象、数组、函数。 如果把这种复杂值也按“简单值”那样复制,会很重,效率很差。
所以 JS 把数据分成:
- 基本类型:适合直接保存和传递
- 对象类型:适合描述复杂结构
这就是它这样设计的核心原因:简单值轻量处理,复杂值按对象结构处理。
3. 底层怎么运行
这里先讲面试里够用、而且比较正确的版本。
3.1 基本类型和对象类型的核心差别
核心不是“长得不一样”,而是:
- 基本类型:值本身就是数据
- 对象类型:变量里拿到的通常不是对象内容本体,而是对对象的引用
看代码:
let a = 10
let b = a
b = 20
console.log(a) // 10
console.log(b) // 20这里 b = a,拷贝的是值本身。 所以改 b 不影响 a。
再看对象:
let obj1 = { name: 'Tom' }
let obj2 = obj1
obj2.name = 'Jack'
console.log(obj1.name) // Jack
console.log(obj2.name) // Jack这里 obj2 = obj1,不是复制出一个新对象, 而是让 obj2 和 obj1 指向同一个对象。
这就是面试里最核心的区别:
- 基本类型赋值:值拷贝
- 对象类型赋值:引用拷贝
3.2 栈内存和堆内存怎么理解
你提到这个了,这里先给你一个面试可用版本。
通常我们会这样理解:
- 栈:保存变量名、执行上下文、一些简单值
- 堆:保存复杂对象的实际内容
比如:
let a = 1
let obj = { name: 'Tom' }可以粗略理解为:
- a 这个变量直接关联值 1
- obj 这个变量保存的是一个地址/引用
- 真正的 { name: 'Tom' } 在堆里
但是注意:
“基本类型一定在栈,对象一定在堆” 这句话是面试简化说法,不是绝对的语言规范定义。
更严谨一点说:
- JS 规范不直接规定“必须怎么放”
- 具体存储由 JS 引擎实现
- 但为了理解,面试里这样讲是可以的
所以你回答时最好这样说:
通常可以理解为,基本类型值更像直接值,对象更像通过引用访问。工程上常用“栈存变量、堆存对象内容”来帮助理解,但具体实现由引擎决定。
这句话就比较稳。
3.3 为什么字符串可以点属性
比如:
const str = 'abc'
console.log(str.length) // 3很多人会疑惑:
不是说基本类型不是对象吗?那为什么还能 str.length?
因为这里发生了 装箱。
JS 引擎在你访问 'abc'.length 这种属性时,会临时把基本类型包装成对应对象:
- string -> String
- number -> Number
- boolean -> Boolean
你可以理解成它临时做了类似这样的事:
const temp = new String('abc')
temp.length
temp 销毁当然这只是帮助理解,不是真实源码。
所以结论是:
- 基本类型本身不是对象
- 但访问属性时会发生临时包装
- 这就是为什么它看起来“像对象一样能点东西”
4. 重点知识点逐个吃透
4.1 null 和 undefined 的区别
它是什么
- undefined:通常表示“定义了,但没有赋值”
- null:通常表示“有意地表示空值”
例子:
let a
console.log(a) // undefined
let b = null
console.log(b) // null为什么这样设计 因为 JS 需要区分两种“空”:
- 一种是“还没有值”
- 一种是“我明确告诉你,这里就是空”
底层怎么运行
undefined 是全局内置的一个原始值。
null 也是一个独立的原始值。
但是有一个历史遗留问题:
typeof null // 'object'这是 JS 早期设计 bug,后来为了兼容一直保留到现在。
实际开发和面试怎么用 你可以这么答:
undefined 表示未定义,null 表示显式空值。虽然 typeof null 返回 object,但 null 本质上是基本类型,这是 JS 的历史遗留问题。
这个就是标准答法。
4.2 typeof 能做什么,不能做什么
它是什么
typeof 用来判断数据类型。
typeof 1 // 'number'
typeof 'a' // 'string'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof 10n // 'bigint'
typeof {} // 'object'
typeof [] // 'object'
typeof null // 'object'
typeof function(){} // 'function'为什么这样设计 因为运行时需要一个很轻量的类型判断方式。
底层怎么运行 它返回的是一个字符串标签,不是完整精确类型系统。
所以它有局限:
- 能很好区分基本类型
- 但对对象细分能力差
- 数组、对象、null 很多都不准
实际开发和面试怎么用 面试里你要会说:
- 判断基本类型,typeof 很方便
- 判断数组不能只靠 typeof
- 判断 null 也不能靠 typeof
判断数组推荐:
Array.isArray(arr)
判断更精确对象类型常用:
Object.prototype.toString.call(value)
例如:
Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call({}) // [object Object]4.3 instanceof 是什么
它是什么
instanceof 用来判断一个对象是否出现在另一个构造函数的原型链上。
[] instanceof Array // true
[] instanceof Object // true为什么这样设计 因为对象在 JS 里是通过原型链关联的,所以判断“是不是某个类型实例”,不能只看表面,得看原型链。
底层怎么运行 它会沿着对象的隐式原型 proto 一直往上找:
看能不能找到构造函数的 prototype
例如:
arr instanceof Array 本质上检查的是:
Array.prototype 是否在 arr 的原型链上。
实际开发和面试怎么用 要注意:
- instanceof 主要用于判断对象
- 不能很好判断基本类型 例如:
1 instanceof Number // false
'abc' instanceof String // false
因为它们是基本类型,不是包装对象实例。4.4 == 和 ===
它是什么
- ===:严格相等,不做类型转换
- ==:宽松相等,会发生隐式类型转换
1 === '1' // false
1 == '1' // true为什么这样设计
JS 早期为了“灵活”和“方便”,设计了宽松比较。
但这也带来了很多坑。
底层怎么运行
== 会按一套复杂规则做类型转换,比如:
'' == 0 // true
false == 0 // true
null == undefined // true
[] == false // true这就是面试常考坑点。
实际开发和面试怎么用
开发里基本原则:优先使用 ===,避免使用 ==
面试里补一句:== 的核心问题在于会触发隐式类型转换,规则复杂且容易出错,因此实际开发通常推荐使用 ===。
5. 一个经典面试题:基本数据类型和 Object 类型有什么区别
这个你前面提到了,我给你一个标准回答模板。
标准答法JavaScript 中,基本数据类型和 Object 类型的核心区别在于:基本类型保存的是值本身,而对象类型访问的通常是引用。
可以展开为 5 点:
值的结构不同基本类型是简单值,比如 number、string、boolean。
Object 类型是复杂结构,可以包含多个属性。赋值行为不同基本类型赋值是值拷贝。
对象赋值是引用拷贝,多个变量可能指向同一对象。比较行为不同基本类型比较通常比较值本身。
对象比较比较的是引用地址是否相同。
{} === {} // false访问能力不同基本类型本身不是对象,但访问属性时会发生装箱。
对象本身就可以直接挂属性和方法。内存理解不同通常可以理解为基本类型更接近直接值,对象类型更接近通过引用访问,实际对象内容通常存放在堆中。
如果你面试这样答,已经比大部分人强了。
6. 实际开发里最容易踩的坑
坑 1:对象赋值以为是复制
const a = { name: 'Tom' }
const b = a
b.name = 'Jack'这里不是复制,是共用一个对象。
坑 2:typeof null
typeof null // 'object'记住:这是历史 bug。
坑 3:数组用 typeof 判断
typeof [] // 'object'正确写法:
Array.isArray([])坑 4:乱用 ==
[] == false // true所以开发中尽量用 ===。
7. 这一章你要背下来的核心结论
这一段建议你直接熟悉到能脱口而出。
结论 1JS 数据类型分为基本类型和对象类型。
结论 2基本类型保存值本身,对象类型通过引用访问。
结论 3基本类型赋值是值拷贝,对象赋值是引用拷贝。
结论 4typeof 适合判断大多数基本类型,但对 null、array、object 的细分能力有限。
结论 5null 表示显式空值,undefined 表示未定义。
结论 6=== 不做隐式类型转换,实际开发应优先使用 ===。
结论 7基本类型不是对象,但访问属性时会发生临时装箱。
8. 你现在先做这几个练习
你先自己不要看答案,试着回答:
- JS 有哪些基本数据类型?
JavaScript 一共有 7 种基本数据类型,分别是 number、string、boolean、null、undefined、symbol、bigint。除此之外,其余复杂值通常都归为对象类型。
- null 和 undefined 的区别是什么?
undefined 通常表示已声明但未赋值,或者访问不存在的属性时得到的值;null 表示开发者有意设置的空值,是一种显式的空对象指针语义。
注意两点:
- undefined 不只是“未定义”,更准确是“缺少值”
- null 不只是“人为设置”,核心是“显式空值”
- 为什么 typeof null === 'object'?
这是 JavaScript 早期实现中的历史遗留问题。typeof 的底层类型标签设计里,null 被错误地判断成了 object,后来为了兼容旧代码,这个行为一直保留到现在。所以 null 本质上是基本类型,不是对象。
这里建议你记一句:
null 是基本类型,typeof null 返回 object 是历史 bug。
- 基本类型和对象类型赋值时有什么区别?
基本类型赋值时复制的是值本身,所以互不影响;对象赋值时复制的是引用,多个变量可能指向同一个对象,因此修改对象内部属性会相互影响。
注意这里是:
- 修改“对象内部属性”会互相影响
- 如果是重新赋值变量本身,不一定互相影响
- 为什么 'abc'.length 可以访问?
因为访问基本类型属性时,JavaScript 会发生临时装箱,把字符串临时包装成对应的 String 对象,属性访问结束后再销毁这个临时对象。
你现在已经知道“装箱”了,这很好。后面面试如果追问 new String('abc') 和 'abc' 的区别,你就能接住。
- typeof 和 instanceof 有什么区别?
typeof 适合判断大多数基本类型,返回的是类型标签字符串;instanceof 适合判断对象是否在某个构造函数的原型链上。typeof 对 null、array、object 的细分能力较弱,而 instanceof 不能很好判断基本类型。
- 为什么开发中更推荐 === 而不是 ==?
因为 == 会触发隐式类型转换,而它的转换规则比较复杂,容易造成歧义和 bug;=== 不会做类型转换,比较更明确、更安全,所以开发中通常优先使用 ===。
9. 面试简答模板
如果面试官问:
“基本数据类型和 Object 类型有什么区别?”
你可以这样答:
JS 中基本数据类型和对象类型的核心区别在于,基本类型保存的是值本身,而对象类型通常通过引用访问。 基本类型赋值时是值拷贝,互不影响;对象赋值时复制的是引用,所以修改一个对象可能影响另一个变量。另外,基本类型本身不是对象,但在访问属性时会发生装箱;对象本身则可以直接拥有属性和方法。工程上通常也会用栈和堆来帮助理解这两类数据的存储差异,但具体实现还是由引擎决定。
