0%

JS核心-23-物件-物件與純值

前言

讓我們了解物件跟純值之間的關係

物件與純值

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

var family = {};
family.name = 'Bob';
console.log(family); // 物件

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

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

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

var num = 10;
console.log(num); // 10
num.name = 'Bob';

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

var num = 10;
console.log(num); // 10
num.name = 'Bob';
console.log(num.name); // undefined

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

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

屬性方法

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

var num = 10;
console.log(num); // 10
num.name = 'Bob';
console.log(num.name); // undefined

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

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

var num = 10;
console.log(num); // 10
num.name = 'Bob';
console.log(num.name); // undefined

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

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

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

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

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

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

JavaScript 只有兩種型別

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

  • String
  • Boolean
  • Number
  • Undefined
  • Null

以及後來新增的

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

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

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

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

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

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

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

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

function fn() {}
console.log(typeof fn); // function
fn.a = 'Bob';
console.log(fn.a); // Bob

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