欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中原始值和引用值深入講解

 更新時間:2022年10月16日 09:40:42   作者:仵波波  
原始值代表原始數(shù)據(jù)類型的值,也叫基本數(shù)據(jù)類型,包括 Number、Stirng、Boolean、Null、Underfined,下面這篇文章主要給大家介紹了關于JavaScript中原始值和引用值深入講解的相關資料,需要的朋友可以參考下

值和引用相關內容

在 JavaScript 中,數(shù)據(jù)類型整體上來講可以分為兩大類:基本類型引用數(shù)據(jù)類型

基本數(shù)據(jù)類型,一共有 6 種:

string,symbol,number,boolean,undefined,null

其中 symbol 類型是在 ES6 里面新添加的基本數(shù)據(jù)類型。

引用數(shù)據(jù)類型,就只有 1 種:

object

基本數(shù)據(jù)類型的值又被稱之為原始值或簡單值,而引用數(shù)據(jù)類型的值又被稱之為復雜值或引用值。

那么兩者之間具體有什么區(qū)別呢?我們一點一點來看:

1. 簡單值(原始值)

簡單值是表示 JavaScript 中可用的數(shù)據(jù)或信息的最底層形式或最簡單形式。簡單類型的值被稱為簡單值,是因為它們是不可細化的。

也就是說,數(shù)字是數(shù)字,字符串是字符串,布爾值是 true 或 false,null 和 undefined 就是 null 和 undefined。這些值本身很簡單,不能夠再進行拆分。

由于簡單值的數(shù)據(jù)大小是固定的,所以簡單值的數(shù)據(jù)是存儲于內存中的棧區(qū)里面的。

要簡單理解棧的存取方式,我們可以通過類比乒乓球盒子來分析。如下圖:

下面是具體的代碼示例:

var str = "Hello World";
var num = 10;
var bol = true;
var myNull = null;
var undef = undefined;
console.log(typeof str); // string
console.log(typeof num); // number
console.log(typeof bol); // boolean
console.log(typeof myNull); // object
console.log(typeof undef); // undefined

這里面 null 比較特殊,打印出來是 object,這是由于歷史原因所遺留下來的問題。

是來源于 JavaScript 從第一個版本開始時的一個 bug,并且這個 bug 無法被修復。因為修復會破壞現(xiàn)有的代碼。

具體原因是因為不同的對象在底層都表現(xiàn)為二進制,在 JavaScript 中二進制前三位都為 0 的話會被判斷為 object 類型,null 的二進制全部為 0,自然前三位也是 0,所以執(zhí)行 typeof 值會返回 object。

例外,當我們打印 null == undefined 的時候,返回的是 true,這也是面試時經(jīng)常會被問到的一個問題。

這兩個值都表示“無”的意思。

通常情況下, 當我們試圖訪問某個不存在的或者沒有賦值的變量時,就會得到一個 undefined 值。Javascript 會自動將聲明是沒有進行初始化的變量設為 undifined。

而 null 值表示空,null 不能通過 Javascript 來自動賦值,也就是說必須要我們自己手動來給某個變量賦值為 null。

那么為什么 JavaScript 要設置兩個表示"無"的值呢?

這其實也是因為歷史原因。

1995 年 JavaScript 誕生時,最初像 Java 一樣,只設置了 null 作為表示"無"的值。根據(jù) C 語言的傳統(tǒng),null 被設計成可以自動轉為 0。

但是,JavaScript 的設計者,覺得這樣做還不夠,主要有以下兩個原因。

  • null 像在 Java 里一樣,被當成一個對象。但是,JavaScript 的數(shù)據(jù)類型分成原始類型(primitive)和復合類型(complex)兩大類,作者覺得表示“無”的值最好不是對象。
  • JavaScript 的最初版本沒有包括錯誤處理機制,發(fā)生數(shù)據(jù)類型不匹配時,往往是自動轉換類型或者默默地失敗。作者覺得,如果 null 自動轉為 0,很不容易發(fā)現(xiàn)錯誤。

因此,作者又設計了一個 undefined。這里注意:先有 null 后有 undefined 出來,undefined 是為了填補之前的坑。

JavaScript 的最初版本是這樣區(qū)分的:

null 是一個表示“無”的對象(空對象指針),轉為數(shù)值時為 0;

典型用法是:

  • 作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對象。
  • 作為對象原型鏈的終點。

undefined 是一個表示"無"的原始值,轉為數(shù)值時為 NaN。

典型用法是:

  • 變量被聲明了,但沒有賦值時,就等于 undefined。
  • 調用函數(shù)時,應該提供的參數(shù)沒有提供,該參數(shù)等于 undefined。
  • 對象沒有賦值的屬性,該屬性的值為 undefined。
  • 函數(shù)沒有返回值時,默認返回 undefined。

2. 復雜值(引用值)

在 JavaScript 中,對象就是一個復雜值。因為對象可以向下拆分,拆分成多個簡單值或者復雜值。

復雜值在內存中的大小是未知的,因為復雜值可以包含任何值,而不是一個特定的已知值,所以復雜值的數(shù)據(jù)都是存儲于堆區(qū)里面。

如下圖所示:

下面是具體的代碼示例:

// 簡單值
var a1 = 0;
var a2 = "this is str";
var a3 = null

// 復雜值
var c = [1, 2, 3];
var d = {m: 20};

3. 訪問方式

按值訪問

簡單值是作為不可細化的值進行存儲和使用的,引用它們會轉移其值。

var str = "Hello";
var str2 = str;
str = null;
console.log(str,str2); // null "Hello"

引用訪問

復雜值是通過引用進行存儲和操作的,而不是實際的值。創(chuàng)建一個包含復雜對象的變量時,其值是內存中的一個引用地址。引用一個復雜對象時,使用它的名稱(即變量或對象屬性)通過內存中的引用地址獲取該對象值。

var obj = {};
var obj2 = obj;
obj.name = "zhangsan";
console.log(obj.name); // zhangsan
console.log(obj2.name); // zhangsan

4. 比較方式

簡單值采用值比較,而復雜值采用引用比較。復雜值只有在引用相同的對象(即有相同的地址)時才相等。即使是包含相同對象的兩個變量也彼此不相等,因為它們并不指向同一個對象。

示例 1:

var a = 10;
var b = 10;
var c = new Number(10);
var d = c;
console.log(a === b); // true
console.log(a === c); // false
console.log(a === c); // false
console.log(a == c); // true
d = 10;
console.log(d == c); // true
console.log(d === c); // false

示例 2:

var obj = {name : 'zhangsan'};
var obj2 = {name : 'zhangsan'};
console.log(obj == obj2); // false
console.log(obj === obj2); // false
var obj3 = {name : 'zhangsan'};
var obj4 = obj3;
console.log(obj3 == obj4); // true
console.log(obj3 === obj4); // ture

5. 動態(tài)屬性

對于復雜值,可以為其添加屬性和方法,也可以改變和刪除其屬性和方法。但簡單值不可以:

var str = 'test';
str.abc = true;
console.log(str.abc); // undefined
var obj = {};
obj.abc = true;
console.log(obj.abc); // true

復雜值支持動態(tài)對象屬性,因為我們可以定義對象,然后創(chuàng)建引用,再更新對象,并且所有指向該對象的變量都會獲得更新。

一個新變量指向現(xiàn)有的復雜對象,并沒有復制該對象。這就是復雜值有時被稱為引用值的原因。復雜值可以根據(jù)需求有任意多個引用,即使對象改變,它們也總是指向同一個對象

var obj = {name : 'zhangsan'};
var obj2 = obj;
var obj3 = obj2;
obj.name = 'abc';
console.log(obj.name, obj2.name, obj3.name);
// abc abc abc

6. 變量賦值

最后說一下關于變量的賦值,其實是可以分為直接賦值和引用賦值的。直接賦值,就是指將簡單值賦值給變量,而引用賦值是指將一個復雜值的引用賦值給變量,這個引用指向堆區(qū)實際存在的數(shù)據(jù)。

直接賦值

var a = 3;
var b = a;
b = 5;
console.log(a); // 3

引用賦值

var a = {value : 1};
var b = a;
b.value = 10;
console.log(a.value); // 10

靈魂拷問

  • JS 的基本數(shù)據(jù)類型有哪些?基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的區(qū)別

參考答案:

在 JavaScript 中,數(shù)據(jù)類型整體上來講可以分為兩大類:基本類型引用數(shù)據(jù)類型

基本數(shù)據(jù)類型,一共有 6 種:

string,symbol,number,boolean,undefined,null

其中 symbol 類型是在 ES6 里面新添加的基本數(shù)據(jù)類型。

引用數(shù)據(jù)類型,就只有 1 種:

object

基本數(shù)據(jù)類型的值又被稱之為原始值或簡單值,而引用數(shù)據(jù)類型的值又被稱之為復雜值或引用值。

兩者的區(qū)別在于:

原始值是表示 JavaScript 中可用的數(shù)據(jù)或信息的最底層形式或最簡單形式。簡單類型的值被稱為原始值,是因為它們是不可細化的。

也就是說,數(shù)字是數(shù)字,字符是字符,布爾值是 true 或 false,null 和 undefined 就是 null 和 undefined。這些值本身很簡單,不能夠再進行拆分。由于原始值的數(shù)據(jù)大小是固定的,所以原始值的數(shù)據(jù)是存儲于內存中的棧區(qū)里面的。

在 JavaScript 中,對象就是一個引用值。因為對象可以向下拆分,拆分成多個簡單值或者復雜值。引用值在內存中的大小是未知的,因為引用值可以包含任何值,而不是一個特定的已知值,所以引用值的數(shù)據(jù)都是存儲于堆區(qū)里面。

最后總結一下兩者的區(qū)別:

訪問方式

  • 原始值:訪問到的是值
  • 引用值:訪問到的是引用地址

比較方式

  • 原始值:比較的是值
  • 引用值:比較的是地址

動態(tài)屬性

  • 原始值:無法添加動態(tài)屬性
  • 引用值:可以添加動態(tài)屬性

變量賦值

  • 原始值:賦值的是值
  • 引用值:賦值的是地址

總結

到此這篇關于JavaScript中原始值和引用值的文章就介紹到這了,更多相關js原始值和引用值內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論