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

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

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

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

二、如何理解值类型和引用类型

以前看到一个比喻,以为很是贴切,想要和你们分享一下:

用“连锁店”和“连锁店钥匙”来理解。

(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复制代码

这里写图片描述
这里写图片描述

引用类型的赋值实际上是对象保存在栈区地址指针的赋值,所以两个变量指向同一个对象,任何的操做都会相互影响。

三、值类型和引用类型的区别

(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。

相关文章
相关标签/搜索