前端基礎
-新手學 JavaScript - 物件 object 基礎觀念,甚麼是物件?如何創建物件?
物件不只是 JavaScript 裡的觀念,而是整個軟體程式語言都會接觸到的名詞。
物件是什麼?
可以把物件想像成一個容器,裡面有很多 key (鍵),每個 key (鍵) 也會有對應的 value (值)。
舉個例子,一個人就可以是一個物件,因為一個人會有名字、年齡、職業...等等資訊,這些資訊的名字和內容就可以組和成一個物件,比如說:
let person1 = {
name: 'thisWeb',
age: 18,
job: 'Front-end Engineer'
}
上面我們創建了一個 person1
物件,物件裡有name、age、job等資訊,這些資訊又叫做物件的屬性。
很多東西都可以用物件表示,例如車子也可以是一個物件,我們在網頁上註冊的會員資料可以是一個物件,所以在 JS 裡,物件是很重要且常見的東西。
創建物件的方法
在JS裡有兩個常用來創建物件的方法,第一種是先創建一個空白的物件,在塞入各種資料給他:
let person1 = new Object();
person1.name = 'thisWeb';
person1.age = 18;
person1.job = 'Front-end Engineer';
但這種方法不常使用,更常用的是向一開始的例子,用大括號 {}
來創建,因為更簡潔:
let person1 = {
name: 'thisWeb',
age: 18,
job: 'Front-end Engineer'
}
( 這個方法又稱 Object literal,台灣的翻譯叫物件實字,對岸的翻譯叫物件字面量,不是很重要,有印象就好 )
當然,物件裡面也可以放函式(function)
let person1 = {
name: 'thisWeb',
age: 18,
job: 'Front-end Engineer'
sayName: function() {
console.log(this.name) // 這裡的this是指person1這個物件
}
}
物件裡放函式也可以簡寫成這樣,省略 : function
:
let person1 = {
name: 'thisWeb',
age: 18,
job: 'Front-end Engineer'
sayName() {
console.log(this.name) // 這裡的this是指person1這個物件
}
}
那物件裡有這些資料後,要如何取得或使用呢?
如何取得物件裡的值(資料)?
第一種方式是利用 物件名字.屬性名字
就可以取得物件屬性的值:
console.log(person1.age) // 18
呼叫函式的方法也是類似的:
person1.sayName() // 'thisWeb'
第二種方式比較少用,是用 [屬性名字]
來調用
console.log(person1['age']) // 18
person1['sayName']() // 'thisWeb'
這種方式要打的字比較多,函式調用看起來也很複雜,所以更推薦第一種用法喔。
物件裡的 this 是什麼?
前面有段程式碼寫了 this.name
,這個 this
是什麼意思呢?
其實很簡單 this
就是指這個物件本身:
let person1 = {
name: 'thisWeb',
age: 18,
job: 'Front-end Engineer'
sayName: function() {
console.log(this.name) // 相當於 person1.name
}
}
使用 this
的好處是,如果有多個物件時,就可以分別使用它的各自的屬性,例如我們現在多了 person2
物件:
let person2 = {
name: '請網這邊走',
age: 15,
job: 'student'
sayName: function() {
console.log(this.name)
}
}
person1.sayName() // thisWeb
person2.sayName() // 請網這邊走
更好創建物件的模式
不知道你有沒有想過一個問題,如果我們要創建100個人,難道要一個一個打嗎,會累鼠掉吧,所以我們可以用一些設計模式,來更輕鬆的創造物件。
分別為:
- 工廠模式
- 構造函數模式
在開始之前,要記得這些模式都是一種設計方法,並不是一個新的語法或函式,他是只是方法。
工廠模式
工廠模式就是把每個函數都當成一個工廠,在工廠內部自己創建一個物件,並且輸出物件 👇
function createPerson(name, age, job) {
let o = new Object();
o.name = name;
o.age = age;
o,sayName = function() {
console.log(this.name)
};
return o;
}
let person1 = createPerson("Jack", 20, "webDeveloper");
let perons2 = createPerson("Rose", 22, "webDesign");
上面的例子可以看出這個工廠是來造人的,可以重複造出好多類似的人。
雖然解決了創建多個類似對象的問題,不過他有個小問題,就是我們沒辦法很好的去識別對象是什麼類型。
就像上面的例子,除非看程式碼,不然無法判斷說 Jack 到底是人還是車子,所以有了接下來的構造函式。
構造函式模式
如果你還記得的話,宣告陣列的其中一個方法是 let arr = new Array()
,宣告物件也有一個方式是 let obj = new Object()
,Object
和 Array
就是JS內建的原生構造函式,我們也可以自定義一個構造函式,像是:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName() {
console.log(name)
}
}
let person1 = new Person('Jack', 18, 'web develope');
let person2 = new Person('Rose', 22, 'web designer');
console.log(person1.constructor === Person) // true
console.log(person2.constructor === Person) // true
console.log(person1 instanceof Object) // true
console.log(person1 instanceof Person) // true
你可以發現我們能用 constructor
或 instanceof
來識別對象的類型,通常認為 instanceof
是確定對象類型比較可靠的方式。
如果有一個物件是用 Person 創造出來的,就稱這個物件為 Person 的實體、實例(instance)。
也要注意,構造函式習慣用大寫開頭,這樣有助於後人來分別是構造函式還是普通函式。
構造函式的特性
構造函式仍然是一個函式,他並不是一個 JS 裡特殊的語法,任何函數只要使用 new
操作調用就是構造函式,不使用 new
就是普通函數:
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name)
}
}
let person1 = new Person('Jack', 18) // 作為構造函式使用
Person('Rose', 20); // 作為普通函式使用
window.sayName(); // "person1" 添加到 window 中
構造函式的問題
構造函式的優點前面說完了,該來說說問題了!在構造函式裡面宣告的函數,會在每一個用構造函數式創建的物件(稱為實例)上都宣告一次,造成資源的浪費:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {console.log(this.name)};
}
console.log(person1.sayName == person2.sayName); // false
有沒有發現一樣功能的函式重複宣告了,造成資源的浪費!所以我們用原型(prototype)來解決這個問題。
原型就像一個大倉庫,讓每個實例都可以來倉庫共用一些資源。
function Person(name, age) {
this.name = name;
this.age = age;
// 將 sayName 放到 prototype 原型上
Person.prototype.sayName = function() {
console.log(this.name)
}
}
let person1 = new Person('Jack', 20);
person1.sayName(); // "Jack"
let person2 = new Person('Rose', 22);
person2.sayName(); // "Rose"
console.log(person1.sayName == person2.sayName); // true
這樣就很好解決資源浪費的問題了!
小結
今天介紹了 JS 裡的物件和創建物件的方法、模式,最常使用的是構造函式,基本上構造函式用於創建和初始化物件,並且通常使用關鍵字 "new" 來調用。
雖然構造函式很好用,但它仍然有一個問題,就是會重複宣告功能相同的函式,造成資源的浪費,所以需要原型 prototype 來解決這個問題,有關原型的深入話題就讓我們留到下次說吧!
今天就這樣,下次見囉!