JavaScript 核心觀念(24)-物件-物件與純值

前言

接下來讓我們了解物件跟純值之間的關係。

物件與純值

首先我們在前面已經知道一個物件實字的宣告方式如下,並且可以透過點運算子新增屬性

1
2
3
var family = {};
family.name = 'Ray';
console.log(family); // 物件

而其他的純值就會向下方範例程式碼這樣

1
2
var num = 10;
console.log(num); // 10

接下來我們針對上方的純值來增加一個屬性

1
2
3
var num = 10;
console.log(num); // 10
num.name = 'Ray';

那這時候我想請問當我輸入 console.log(num.name) 時,會出現什麼?

1
2
3
4
var num = 10;
console.log(num); // 10
num.name = 'Ray';
console.log(num.name); // undefined

在這邊有一個關鍵的重點,純值是不允許新增屬性的。

但是這邊你應該會疑惑純值不允許新增屬性的話,那這些屬性方法哪裡來的呢?

屬性方法

這些方法都是繼承原始物件型別來的,什麼意思呢?首先假使我直接針對 Number 增加一個 prototype 叫做 qq123 並賦予一個值叫做 Ray,那麼這時候呼叫 num.qq123 會發生什麼事情?

1
2
3
4
5
6
7
var num = 10;
console.log(num); // 10
num.name = 'Ray';
console.log(num.name); // undefined

Number.prototype.qq123 = 'Ray';
console.log(num.qq123); // Ray

但是這邊要注意,純值是不允許新增屬性的這個重點,因此就算你修改屬性的值也會無效,因為他是繼承而來的。

1
2
3
4
5
6
7
8
9
var num = 10;
console.log(num); // 10
num.name = 'Ray';
console.log(num.name); // undefined

Number.prototype.qq123 = 'Ray';
console.log(num.qq123); // Ray
num.qq123 = 'Hello';
console.log(num.qq123); // Ray

簡單來講,你是繼承你爸爸的 DNA 但你沒辦法任意修改你爸的基因啦~

除此之外,若你使用建構子 new 宣告的型別都是一個物件

1
2
var a = new Number('123');
console.log(typeof a); // Object

並且透過建構子建構的型別,是具有物件新增的能力,因為他本身就是一個物件

1
2
3
4
var a = new Number('123');
console.log(typeof a); // Object
a.name = 'Ray';
console.log(a.name); // Ray

JavaScript 只有兩種型別

首先 JavaScript 只有兩種型別,也就是物件與純值,也就是說除了以下型別之外通通都是物件

  • String
  • Boolean
  • Number
  • Undefined
  • Null

以及後來新增的

  • Bigint - 目前僅有部分瀏覽器實作。
  • Symbol

但是這時候你可能會說 Array 與 Function 呢?首先我們可以透過 typeof 了解到 Array 是一個物件

1
2
var arr = [1,2];
console.log(typeof arr); // Object

這一點並不是 JavaScript 的 Bug,而是 JavaScript 的陣列其實是一個假陣列,因此你是可以針對他增加屬性的

1
2
3
var arr = [1,2];
console.log(typeof arr); // Object
arr.name = "Ray"; // [1, 2, name: "Ray"]

那這時候你可能會說 function 不可能是物件,畢竟透過 typeof 顯示的是一個 function 的字樣

1
2
function fn() {}
console.log(typeof fn); // function

那這時候該如何驗證其實 function 也是一個物件呢?我們可以透過點運算子來新增屬性

1
2
3
4
function fn() {}
console.log(typeof fn); // function
fn.a = 'Ray';
console.log(fn.a); // Ray

這邊要額外注意一件事情,function 本身有一個 name 的屬性,而這個 name 是對應 function 的名稱,因此是無法修改的,而 function 只是多了可以被呼叫且可以撰寫程式碼片端的能力,所以 function 本身還是一個物件。

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
當然你也可以成為 讚賞公民 每個月請我喝一杯咖啡,又或者是 一次性金額抖內

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ