这一次搞明白JavaScript中变量、指针和引用

227 阅读2分钟

说起js中的数据类型,分为了“基本类型”和“引用类型”,其中基本类型又包含了:null、undefined、Number、String和Boolean;而引用类型就指的是对象。

基本类型

基本类型存放在了栈区,访问是按值访问的,当基本类型的数据赋值时,赋的是实际的值

var a
a = 'hello world'

我们定义了一个变量a,就是在存储器中定义了一个存储单元,将之命名为a,接下来,给变量a进行赋值'hello wordl',也就是在这组存储单元中存储了字符串'hello world'

我们可以对这个存储单元进行任意的修改

a = 6

同时我们定义变量b,也将之赋值为6

var b = 6

a和b是不相关联的,相互独立的,只是这两个存储单元的内容恰巧相等

a === b // true

引用类型

对象的使用是引用赋值,当我们把一个对象赋值给一个变量的时候,其实只是将对象在堆中的地址赋值了给了变量,并不是堆中的数据。而这个变量我们就称之为指针(指向对象的存放位置)

var obj1 = {name: 'eric'}
var obj2 = {name: 'eric'}

obj1 === obj2 // false
obj1 == obj2 // false

为什么两个变量赋予了相同内容的对象,他们却并不相等,这是因为当我们给obj1进行赋值的时候,实际上是在堆内存中创建了一个对象{name: 'eric'},并将这个对象的地址赋予了变量obj1,即obj是一个指针,指向了{name: 'eric'};创建obj2的时候,又创建了一个对象{name: 'eric'},同样的将所创建的对象的地址赋予了obj2,虽然创建的这两个对象的内容相同,但是他们是先后创造出来的,并不是堆中的同一组对象数据,也就是obj1和obj2两个指针所指向的地址是不同的。

在js中,引用类型的比较,实际上是必将指针是否指向存储器中同一个地址,只有指向同一地址的才是相等的

var obj2 = {name: 'eric'}
var obj2 = obj1
obj1 == obj2 // true
obj1 === obj2 // true

虽然上面的代码看起来很傻,但是他充分展示了,在对象使用= 赋值的时候,就是将对象的地址赋值给变量的过程

在传参的过程中,基本类型传值,引用类型传引用

var a = 1, b = 2
function fn (a, b) {
    a += 10
    b += 20
    console.log(a) // 11
    console.log(b) // 22
}
fn(a, b)
console.log(a) // 1
console.log(b) // 2

var obj = {
    name: 'nice'
}
function fn (obj) {
    obj.name = 'eric'
    console.log(obj.name) // 'eric
    obj = {}
    obj.name = 'super6'
    console.log(obj.name) // 'super6'
}
fn(obj)
console.log(obj.name) // eric