<style>
.slides img{background-color:grey!important}
.slides img[title^='"']{filter:invert(100%)}
hr, .slides [title^='*']{display:none}
summary h1{display:inline;border-bottom:0!important}
</style>
<!-- .slide: data-background="black" -->
###### [JavaScript 教學/](/@NCHUIT/js)
:::spoiler {state=open}<h1>物件導向</h1>
+ <i class="fa fa-book"></i> 網頁 md.nchuit.cc/js
+ <i class="fa fa-tv"></i> 簡報 md.nchuit.cc/js2</span>
- [MDN](https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/Objects)
- [W3schools](https://www.w3schools.com/js/js_objects.asp)
[ToC]
:::
> [name=VJ]
----
## 物件
object (n.)
: 物件,最主要的組成就是 屬性 和 方法
屬性即 變數,方法即 函式
*[屬性]: attribute
*[方法]: method
*[變數]: variable
*[函式]: function
再看一次我們體驗社課和上次時看到的例子
```javascript=!
var 某人 = {
暱稱 : 'VJ',
年齡 : 22,
性別 : '男',
興趣 : ['看韓劇', '睡覺', '電腦遊戲'],
高中畢業與否 : true,
打招呼: function() {
alert('Hello world')
}
}
```
~~有人看膩了??~~
----
:::spoiler 練習
+ 某人.暱稱: 'VJ'
+ 某人.年齡+1: 23
+ 某人.打招呼: f() {} (說它是函式的意思)
+ 某人.打招呼(): 冒出顯示「Hello world」的對話框
+ 某人.興趣[0'](/STsRyvR3T4unX2SZb5T1SQ)
:::
取取看`某人.暱稱`、`某人.年齡+1`、
`某人.打招呼`、`某人.打招呼()`、
`某人.興趣[0]`、`某人.興趣[2]`、
----
練習2
執行上面的
```javascript=
var 某人 = {
...
}
```
再執行
```javascript=
某人.年齡+=1
某人.打招呼=function() {
alert('bye bye')
}
某人.興趣
```
問: 之後取`某人.年齡`是多少
問: 之後取`某人.打招呼()`會出現什麼
問: 之後取`某人.興趣`會出現什麼
---
## 屬性
Attribute (n.)
: 對物件內**變數**專用的代名詞
取法
1. 用點號`.`取
```javascript=
某人.興趣
```
2. 用方括號`[]`取字串索引
```javascript=
某人['興趣']
```
----
### 方法
Method (n.)
: 對物件內**函式**專用的代名詞
一樣兩種取法
```javascript=
某人.打招呼
某人["打招呼"]
```
#### 使用/呼叫
```javascript=
某人.打招呼()
某人["打招呼"]()
```
----
::: spoiler 練習: 選取/修改元素
```javascript=
大標題 = document.getElementById('大標題')
大標題.innerHTML='我是標題啊'
大標題.style.color='red'
```
:::
```htmlembedded=
<h1 id='大標題'>我不是標題</h1>
<script>
//TO-DO 或直接用主控台
</script>
```
搭配上次提到的<kbd>Ctrl+Shift+C</kbd>選取網頁元素
1. 使用文件物件 `document` 的 `getElementById('id')` 方法,取得上面 `未命名網頁.html` 的大標題
2. 將取得物件的 內文`innerHTML` 改成(重新宣告成) `我是標題啊`
3. 將取得物件的 樣式`style` 中的 顏色`color` 改成 紅色`'red'`
---
## [類別](https://www.w3schools.com/js/js_class_intro.asp)
class (n.)
: 類別,就是物件的藍圖

###### 這是 Python
----
語法
```javascript=
類別 = class{...} //第1種寫法
class 類別{...} //第2種寫法
```
宣告區塊中用`;`而不是`,`做區隔,也可以省略
```javascript=[|8,11]
人 = class{ //回來JS
constructor(暱稱,年齡,性別,興趣,高中畢業與否){
this.暱稱=暱稱
this.年齡=年齡
this.性別=性別
this.興趣=興趣
this.高中畢業與否=高中畢業與否
}
打招呼() {
alert('Hello world')
}
}
```
----
也可以使用`class x{}`宣告,沒有`=`
```javascript=[|1]
class 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否){
this.暱稱=暱稱
this.年齡=年齡
this.性別=性別
this.興趣=興趣
this.高中畢業與否=高中畢業與否
}
打招呼() {
alert('Hello world')
}
}
```
this (n.)
: **保留字**,**限**在物件中使用的字詞,同 Java

----
### 建構子
constructor (v.)
: 用來 `new`,`new`時注意會換成「類別」的名字,如上面取作「某人」,我們就用`某人1 = new 某人(...)`來生成物件
[](https://store.line.me/stickershop/product/7034336/zh-Hant?from=sticker)
###### `__init__()`是 Python 的建構子,Python 不用 new
----
new (v.)
: **保留字**,用 **類別名稱**(**Class Name**) 取代建構子以**描繪/建構**(**construct**) 物件,語法同 Java
```javascript=
某人1 = new 人('VJ', 22, '男', ['看韓劇', '電腦遊戲'], true)
某人2 = new 人('??', 13, '女', ['念書', '化妝'], false)
某人3 = new 人('!!', 42, '男', ['綜藝', '政治'], false)
某人4 = new 人('@@', 20, '女', ['貓咪', '狗勾'], true)
```
就...重複使用會比較短/便捷,同函式
做做接下來的練習你就知道為啥需要ㄓㄟˋ個
----
:::spoiler 練習: 試直接寫出上面`new`出來的物件,提示:
```javascript=
某人1 = {
暱稱: 'VJ',
年齡: 22,
性別: '男',
興趣: ['看韓劇', '電腦遊戲'],
高中畢業與否: true,
打招呼: function() {
alert('Hello world')
}
}
某人2 = {
暱稱: '??',
年齡: 13,
性別: '女',
興趣: ['念書', '化妝'],
高中畢業與否: false,
打招呼: function() {
alert('Hello world')
}
}
某人3 = {
暱稱: '!!',
年齡: 42,
性別: '男',
興趣: ['綜藝', '政治'],
高中畢業與否: false,
打招呼: function() {
alert('Hello world')
}
}
某人4 = {
暱稱: '@@',
年齡: 20,
性別: '女',
興趣: ['貓咪', '狗勾'],
高中畢業與否: true,
打招呼: function() {
alert('Hello world')
}
}
```
:::
```javascript=
物件1 = {
屬性1: 屬性1值,
屬性2: 屬性2值,
...
方法1(){ ... }
}
物件2 = { ... }
```
----
## 繼承

----
一樣可以用`=`宣告,這裡略。
在原有的類別多加點東西,取成其它名字
```javascript=
class 壞人 extends 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否,壞事) {
super(暱稱,年齡,性別,興趣,高中畢業與否)
this.壞事=壞事
}
打招呼() {
super.打招呼()
this.你的回應 = prompt('do three small')
}
挑事() {
alert(你的回應+"?! 你是想找碴嗎?")
}
會做的事(){
this.打招呼()
this.挑事()
}
}
```
----
[super](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/super) (v.)
: **保留字**,只能寫在函式或建構元的第一行,引用原先**同名**的程序,下面可以再加點東西,要不然就TM別寫,給我省略,本來就有的東西
[static](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Classes/static) (adj.)
: **保留字**,將屬性或方法設為**靜態**,讓你在全域可以取用 `類別.static變數`。例如: `Math.PI` 就是 `static` 變數。取類別中不是靜態的方法或屬性會噴錯
----
:::spoiler 練習: 讓`壞人.會做的事()`可以直接呼叫
```javascript= [|9|18,19,23,24,26]
class 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否){
this.暱稱=暱稱
this.年齡=年齡
this.性別=性別
this.興趣=興趣
this.高中畢業與否=高中畢業與否
}
static 打招呼() {
alert('Hello world')
}
}
class 壞人 extends 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否,壞事) {
super(暱稱,年齡,性別,興趣,高中畢業與否)
this.壞事=壞事
}
static 你的回應
static 打招呼() {
super.打招呼()
this.你的回應 = prompt('do three small')
}
static 挑事() {
alert(this.你的回應+"?! 你是想找碴嗎?")
}
static 會做的事(){
this.打招呼()
this.挑事()
}
}
```
:::
----
### [私用 `#`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Private_class_fields)
[](https://store.line.me/stickershop/product/1439141/zh-Hant?from=sticker)
類別的屬性或方法在默認情況下是共用(public)的,在屬性或方法的最前面加 `#` 宣告成私用(private)的。
----
```javascript=
class 有私用靜態屬性的類別 {
static #私用靜態屬性='hello';
static 靜態屬性='hello';
}
class 有私用靜態方法的類別 {
static #私用靜態方法() {
alert('hello world');
}
static 靜態方法() {
alert('hello world');
}
}
```
用處? 就...讓你用不了(`static` 來說的話啦)
```javascript=
有私用靜態屬性的類別.靜態屬性
有私用靜態屬性的類別.#私用靜態屬性 //nope
有私用靜態方法的類別.靜態方法()
有私用靜態方法的類別.#私用靜態方法() //nope
```
{"metaMigratedAt":"2023-06-16T20:04:23.017Z","metaMigratedFrom":"YAML","breaks":true,"description":"JavaScript教學-110-2主題社課-國立中興大學資訊科學研習社","title":"物件導向","contributors":"[{\"id\":\"e86b6571-4dea-4aa4-ba20-ece559b0e015\",\"add\":12352,\"del\":4747},{\"id\":\"6d6e3ba2-6820-4c6f-9117-f09bccc7f7aa\",\"add\":550,\"del\":1602}]"}