JavaScript 基本数据类型和引用数据类型的区别

1.动态属性

原始值和引用值的定义方式很类似,都是创建一个变量,然后给它赋一个值。不过,在变量保存了 这个值之后,可以对这个值做什么,则大有不同。对于引用值而言,可以随时添加、修改和删除其属性和方法。比如,看下面的例子:
原始值不能有属性,尽管尝试给原始值添加属性不会报错。比如

2.复制值

原始值和引用值在通过变量复制时也有所不同。在通过变量把一个原始值赋值
到另一个变量时,原始值会被复制到新变量的位置。请看下面的例子:
这里, num1 包含数值 5 。当把 num2 初始化为 num1 时, num2 也会得到数值 5 。这个值跟存储在 num1 中的 5 是完全独立的,因为它是那个值的副本。
这两个变量可以独立使用,互不干扰。
在把引用值从一个变量赋给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置。区
别在于,这里复制的值实际上是一个指针,它指向存储在堆内存中的对象。
在这个例子中,变量 obj1 保存了一个新对象的实例。然后,这个值被复制到 obj2 ,此时两个变
量都指向了同一个对象。在给 obj1 创建属性 name 并赋值后,通过 obj2 也可以访问这个属性,因为 它们都指向同一个对象。图 4-2 展示了变量与堆内存中对象之间的关系。

3.传递参数

ECMAScript 中所有函数的参数都是按值传递的。这意味着函数外的值会被复制到函数内部的参数
中,就像从一个变量复制到另一个变量一样。如果是原始值,那么就跟原始值变量的复制一样,如果是 引用值,那么就跟引用值变量的复制一样。
,如果是 引用值,那么就跟引用值变量的复制一样。对很多开发者来说,这一块可能会不好理解,毕竟变量有按 值和按引用访问,而传参则只有按值传递。
俩面两个例子:
这一次,我们创建了一个对象并把它保存在变量 person 中。然后,这个对象被传给 setName()
方法,并被复制到参数 obj 中。在函数内部, obj person 都指向同一个对象。结果就是,即使对象 是按值传进函数的,obj 也会通过引用访问对象。当函数内部给 obj 设置了 name 属性时,函数外部的 对象也会反映这个变化,因为 obj 指向的对象保存在全局作用域的堆内存上。很多开发者错误地认为, 当在局部作用域中修改对象而变化反映到全局时,就意味着参数是按引用传递的。为证明对象是按值传 递的,我们再来看看下面这个修改后的例子:
这个例子前后唯一的变化就是 setName() 中多了两行代码,将 obj 重新定义为一个有着不同 name
的新对象。当 person 传入 setName() 时,其 name 属性被设置为 "Nicholas" 。然后变量 obj 被设置
为一个新对象且 name 属性被设置为 "Greg" 。如果 person 是按引用传递的,那么 person 应该自动将 指针改为指向 name "Greg" 的对象。可是,当我们再次访问 person.name 时,它的值是 "Nicholas" , 这表明函数中参数的值改变之后,原始的引用仍然没变。当 obj 在函数内部被重写时,它变成了一个指 向本地对象的指针。而那个本地对象在函数执行结束时就被销毁了。

4.确定类型

  typeof 操作符最适合用来判断一个变量是否为原始类型。更确切地说,它是判断一
个变量是否为字符串、数值、布尔值或 undefined 的最好方式。如果值是对象或 null,返回 "object"
typeof 虽然对原始值很有用,但它对引用值的用处不大。
如果变量是给定引用类型(由其原型链决定, )的实例,则 instanceof 操作
符返回 true;
即:一个构造函数的prototype属性是否出现在某个实例对象的原型链上。
8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值