###### 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)
```