---
# System prepended metadata

title: prototype
tags: [JavaScript]

---

###### tags: `JavaScript`

# prototype

1. 創建一個arr解釋原型
2. 演示各種型態原型指向物件
3. 創建一個類陣列比較
```javascript!
function foo() {
    const arr = Array.prototype.slice.call(arguments);
    console.log(arguments); // (1)
    console.log(arr); // (2)
}
let testList = foo('hello', 'world', 'bar', 'baz'); // ->類陣列

```
4. call by value and ref....
```javascript!
const allen = {
    sex:"男",
    saySex(){
        if(this.sex === '男'){
            console.log("我是男生")
        }else{
            console.log("我不是男生")
        }
    }
}
const alice = allen
alice.sex='女'
alice.saySex()
allen.saySex()
```
5. 建構式
```javascript!
function Person(sex){
    this.sex = sex
    this.saySex = function(){
        if(sex === '男'){
            console.log("我是男生")
        }else{
            console.log("我不是男生")
        }
    }
}
Person.prototype.sayMore = function(){
    if(this.sex==='女'){
        console.log("我是一個美女")
    }else{
        console.log("我是一個帥哥")
    }
}
const alice = new Person("女")
alice.__proto__.play = function(){
    if(this.sex==="男"){
        console.log("我要玩遙控器車")
    }
    if(this.sex==="女"){
        console.log("我要玩芭比娃娃")
    }
}
alice.saySex()
alice.sayMore()
alice.play()

const allen = new Person("男")
allen.sayMore()

```















## 原型對象
1. 創建一個新對象son
2. 新對象會被執行[[prototype]]連接
son.\_\_proto_\_=Mother.prototype;
3. 新對象和函數調用的this會綁定
Mother.call(son,"Da");
4. 執行建構式中的的程式
son.lastName;
5. 如果函數沒有返回值，那麼就會自動返回這個新對象

```javascript=
function Mother(lastName) {
    this.lastName = lastName
}
const son = new Mother("Da");

function Mother2(lastName) {
    this.lastName = lastName;
    return this
}
const son2 = Mother2("Da2");
console.log(son.lastName)
console.log(son2.lastName)
```
## 原型鏈
```javascript!
function Supermarket() {
    Supermarket.prototype.product = "口罩"
}
//person.__proto__ = Supermarket.prototype
function Shop() {
    Shop.prototype = new Supermarket()
}
//默認person.__proto__ = Shop.prototype
const person = new Shop();

// console.log(person)

const greeting = ['新年快樂', '恭喜發財', '身體健康'];
console.log(greeting instanceof Array,greeting)
```

## class繼承
```javascript!
class Person{
    constructor(name){
        this.name=name
    }
    drink(){
        console.log("喝水")
    }
}


class Student extends Person{
    constructor(name,score){
        super(name)
        this.score =score
    }

    introduce(){
        console.log(`我是${this.name},考${this.score}分`)
    }
}

const student = new Student("張三",99)
console.log(student)
student.introduce()
class Teacher extends Person{
    constructor(name,subject){
        super(name)
        this.subject =subject
    }

    teach(){
        console.log(`我是${this.name},教${this.subject}`)
    }
}
const teacher = new Teacher("王五","數學")
console.log(teacher)
teacher.teach()
```
## class的原型
```javascript!
class Student{
    constructor(name,score){
        this.name=name
        this.score =score
    }

    introduce(){
        console.log(`我是${this.name},考${this.score}分`)
    }
}

const student = new Student("張三",99)
console.log(student)
console.log(student.__proto__)
console.log(Student.prototype)
console.log(
    student.__proto__===Student.prototype
    //隱式原型            顯示原型
)
```
## instanceof
```javascript!
const obj = {}
const array = []


console.log("typeof obj",typeof obj)
console.log("typeof array",typeof array)

const objIsArray = obj instanceof Array
const arrayIsArray = array instanceof Array
console.log("objIsArray",objIsArray)

```