iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
自我挑戰組

追憶JS年華系列 第 21

Day-21 物件與原型鏈

  • 分享至 

  • xImage
  •  

JavaScript的物件基於「原型」的繼承,可以令一個物件「繼承另一個物件的屬性」。具體上,以 Object.setPrototypeOf() 指定原型關係。詳:
『Object.setPrototypeOf() - JavaScript | MDN』

建立空物件

所有的物件都有proto屬性

  • 預設是 prototype = { }。
  • 使用後可以找到他的原型。___proto___找東西,會往Array.prototype找。
  • .map 方法其實是 prototype 裡面的屬性,後面的值是 function,用來做事。
//  對 prototype 物件新增 attack 屬性,值是後面的 function
Hero.prototype.attack = function() {
    console.log("attack")
//  
}

寫法1

  • 先宣告一個空陣列,填入屬性
  • 若key與value同名,可從 名字:名字 {name:name}改為 名字,
const a = { } // 空物件寫法

寫法2

const b = Object.create(null)  // 指定原形,建立新物件

延伸:建構函式

函式(function)如同 { } 可以用來建構物件,把他當成一般物件來用可以做到以下的事。

  • 物件都有___proto___屬性。
  • 所有function都有prototype屬性,預設的 { } 是空陣列。
function heroCreater(name, action) {

    const attack = () => {
        console.log(`${name}使用絕招${action}`)
    }
    return {
        name,
        action,
        attack
        //  當參數和屬性同名時,可省略值不寫
        //  原本應該長成 name: name,
    }
}

const h = heroCreater("小傑", "剪刀石頭石頭")
h.attack()
//  "小傑使用絕招剪刀石頭石頭"
console.log(h)
//  [object Object] {
//  action: "剪刀石頭石頭",
//  attack: () => {
//        window.runnerWindow.proxyConsole.log(`${name}使用絕招${action}`)
//    },
//  name: "小傑"
// }
console.log(h.action)
//  "剪刀石頭石頭"

原型鏈 prototype chain

  • 連續使用__proto__可以一層一層往上找到原型。
  • 正常之下,印出沒有的屬性應該要會得到 Error,但在 JS 會得到 undefined,若再呼叫會得到 TypeError。
  • 建構函式,通常會把函式名稱的首字改成大寫 hero => Hero ,方便辨識這是「物件」。
function Hero(name, action) {
  this.name = name
  this.action = action
}

若const對function加new

  1. 建立一個空物件
  2. 把 this指向空物件 { }
  3. 把 this.proto 指向 Hero.prototype (預設值: { } )
  4. 自動 return this (自己多加return沒用,除非是物件或陣列)
function hello() {
  console.log("hi")
}

const h = new hello()
console.log(h)
//  hello { } ,裡面的 this = 函式名稱 + 空物件
console.log(this)
//  { } ,外面的 this 空物件
---------------------------
const h = hello()
console.log(h)
//  undefined,沒有 return 值

所有的 function 都有回傳值,當沒有寫 return 時會有兩種預設值:

  • 一般的 function 會回傳 undefined
  • 使用 new 建立的 function 會回傳 this 的值
    • Class 就像藍圖
    • Instance就像new出來的實體

建構子 constructor

JavaScript沒有class,這是ES6才有的語法糖衣,本質上還是使用__proto__去做事。結構可以看成:

class => new => instance(實體)
(烤盤) (透過) (雞蛋糕)

如果 new Hero() 想帶引數進去,一定要搭配建構子constructor()使用。
constructor 裡面只放屬性,行為請寫在外面。

class Hero {
    constructor(name) {
        this.name = name
    }
}
let h = new Hero("奇犽")
console.log(h)

上一篇
Day-20 OOP與抽象類別
下一篇
Day-22 操作方法:BOM與DOM
系列文
追憶JS年華30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言