三分鐘帶你理解JS原型

Colin_Mindset發表於2019-02-21

一. 理論基礎

1. 普通物件和函式物件

JavaScript中,萬物皆物件!但是物件也是有區別的,分為普通物件函式物件

function F(){}; //F:普通物件
var f = new Function(); //f: 函式物件
var o = new Object(); //o: 函式物件

Object、Function是js自帶的函式物件。

2. 建構函式

與大部分物件導向的語言不同,JavaScript中並沒有引入類(class)的概念,但JavaScript仍然大量使用了物件,為了保證物件之間的聯絡,JavaScript引入了原型與原型鏈的概念。
與Java不同,JavaScript的new操作符後面跟的並非類名而是函式名,JavaScript並非通過類而是直接通過建構函式來建立例項

function Dog(name, color) {
    this.name = name
    this.color = color
    this.bark = () => {
        console.log('wangwang~')
    }
}

const dog1 = new Dog('dog1', 'black')
const dog2 = new Dog('dog2', 'white')

上述程式碼中,有兩個例項被建立,它們有自己的屬性,但bark方法是一樣的,而通過建構函式建立例項的時候,每個例項都需要建立這個方法為什麼不把這個方法放到一個單獨的位置,並讓所有例項都可以訪問到呢

3. 建構函式和普通函式

建構函式和普通函式主要有以下區別:

  • 呼叫方式:
    (1)建構函式需要使用new運算子呼叫,如果沒有引數,可以省略括號,比如new Object
    (2)普通函式的呼叫不需要new運算子,而且必須有括號

  • this指向
    (1)建構函式的this會指向建立的物件例項上
    (2)普通函式的this則指向函式的呼叫者

  • 命名方式
    (1)建構函式名稱首字母要大寫
    (2)普通函式首字母要小寫,使用駝峰命名方式


這裡就需要用到原型。

二. 原型

  • 每一個建構函式都有一個prototype屬性,指向原型物件。當使用這個建構函式建立例項的時候,prototype屬性指向的原型物件,就是例項的原型物件
  • 原型物件預設擁有一個constructor屬性,指向指向它的那個建構函式。
  • 每個物件都有一個隱藏屬性obj._proto_,每個函式物件都有一個function.prototype,它們指向同一原型物件。
  • 原型物件就是用來存放例項中共有的屬性。
  • 訪問物件屬性時,會先在物件自身屬性內查詢,若沒有找到,則會跳轉到物件的原型物件中查詢。

那麼上述程式碼就可以修改為

 function Dog(name, color) {
    this.name = name
    this.color = color
}

Dog.prototype.bark = () => {
    console.log('wangwang~')
}

接著就可以建立例項,並訪問它的bark方法:

 const dog1 = new Dog('dog1', 'black')
dog1.bark()  //'wangwang~'

這個時候,我們還可以重寫bark方法:

const dog2 = new Dog('dog2', 'white')
dog2.bark = () => {
    console.log('miaomiaomiao???')
}
dog1.bark()  //'wangwang~'
dog2.bark()  //'miaomiaomiao???'

由上可知,重寫的bark方法是為自己新增了一個新的方法使原型中的bark方法被覆蓋了,而並非直接修改原型中的方法。
要修改原型中的方法應該這樣:

Dog.prototype.bark = () => {
    console.log('haha~')
}
dog1.bark()  //'haha~'
dog2.bark()  //'haha~'

三. 結語

如有遺漏,後面會繼續總結。

參考
https://www.jianshu.com/p/dee9f8b14771
https://juejin.im/post/5a94c0de5188257a8929d837
https://www.cnblogs.com/shayueblog/p/5813230.html
http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html

相關文章