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。

相關文章
相關標籤/搜索