JS基本类型与引用类型知多少

1、JavaScript值类型和引用类型有哪些

(1)值类型(基本类型):数值(number)、布尔值(boolean)、null、undefined、string(在赋值传递中会以引用类型的方式来处理)。

(2)引用类型:对象、数组、函数。

2、如何理解值类型和引用类型
之前看到一个比喻,觉得非常贴切,想要和大家分享一下:
用“连锁店”和“连锁店钥匙”来理解。
(1)值类型:变量的交换等于在一个新的地方按照连锁店的规范标准(统一店面理解为相同的变量内容)新开一个分店,这样新开的店与其它旧店互不相关、各自运营。
function str() 
{ 
var str1='Hello World'; 
var str2=str1; 
str1='Hello'; 
alert(str2); //Hello World 
} 
str();复制代码
把一个值类型(也叫基本类型)str2赋值给另一个变量时,其实是分配了一块新的内存空间,因此改变str1的值对str2没有任何影响,因为它不同于引用类型(变量的交换其实是交换了指像同一个内容的地址)。
再看一个例子:
var a = 1;
var b = a;

a ++ ;
console.log(a); // 2
console.log(b); // 1复制代码
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上。
例子中,一开始,a中保存的值为 1 ,当使用 a 来初始化 b 时,b 中保存的值也为1,但b中的1与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量可以参加任何操作而相互不受影响,即基本类型在赋值操作后,两个变量是相互不受影响的。

这里写图片描述
(2)引用类型:变量的交换等同于把现有一间店的钥匙(变量引用地址)复制一把给了另外一个老板,此时两个老板同时管理一间店,两个老板的行为都有可能对一间店的运营造成影响。
function str() 
{ 
var str1=['Hello World']; 
var str2=str1; 
alert(str2[0]); //Hello World 
str1[0]='Hello'; 
alert(str2[0]); //Hello
} 
str();复制代码
str2只进行了一次赋值,理论上它的值已定,但后面通过改写str1的值,发现str2的值也发生了改变,这正是引用类型的特点。
再看个例子:
var a = {}; // a保存了一个空对象的实例
var b = a;  // a和b都指向了这个空对象

a.name = 'coco';
console.log(a.name); // 'coco'
console.log(b.name); // 'coco'

b.age = 24;
console.log(b.age);// 24
console.log(a.age);// 24

console.log(a == b);// true复制代码

这里写图片描述
引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
3、值类型和引用类型的区别
(1)基本类型的值是一经确定就不可变的
(2)基本类型的比较是值的比较
只有在它们的值相等的时候它们才相等。
比较的两个值的类型不同的时候==运算符会进行类型转换,但是当两个值的类型相同的时候,即使是==也相当于是===。
var a = 1;
var b = true;
console.log(a == b);//true复制代码
在用==比较两个不同类型的变量时会进行一些类型转换。如上的比较先会把true转换为数字1再和数字1进行比较,结果就是true了。
var a = 'coco';
var b = 'coco';
console.log(a === b);//true复制代码
(3)基本类型的变量是存放在栈区的(栈区指内存里的栈内存)
var name = 'coco';
var city = 'shenzhen';
var age = 24;复制代码
存储结构如下:

这里写图片描述
栈区包括了 变量的标识符和变量的值。
(4)引用类型的值是可变的
可以为引用类型添加属性和方法,也可以删除其属性和方法。
var person = {};//创建一个空对象 --引用类型
person.name = 'coco';
person.age = 24;
person.sayName = function(){
console.log(person.name);
} 
person.sayName();// 'coco'复制代码
var person = {};//创建一个空对象 --引用类型
person.name = 'coco';
person.age = 24;
person.sayName = function(){
console.log(person.name);
} 
person.sayName();// 'coco'
delete person.name; //删除person对象的name属性
person.sayName(); // undefined复制代码
引用类型可以拥有属性和方法,并且是可以动态改变的。
(5)引用类型的值是同时保存在栈内存和堆内存中的对象
js不同于其他语言,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,实际上,是操作对象的引用,所以引用类型的值是按引用访问的。
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。
var person1 = {name:'zhangsan'};
var person2 = {name:'lisi'};
var person3 = {name:'wangwu'};复制代码
则这三个对象的在内存中保存的情况如下图:

这里写图片描述
(6)引用类型的比较是引用的比较
var person1 = '{}';
var person2 = '{}';
console.log(person1 == person2); // true复制代码
基本类型的比较--当两个比较值的类型相同的时候,相当于是用 === ,所以输出是true。
var person1 = {};
var person2 = {};
console.log(person1 == person2); // false复制代码
上面比较的是两个字符串,而下面比较的是两个对象,为什么长的一模一样的对象就不相等了呢?
引用类型是按引用访问,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不同的:

这里写图片描述
这两个是完全不同的对象,所以返回false。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值