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 本身還是一個物件。

參考文獻

0%