從 React 一步步理解 Javascript 原型鍊

1. 與 class 的第一次相遇
2. class 語法糖的背後
3. 原型鍊  __proto__  與  prototype

與 class 的第一次相遇

class Articles extends PureComponent {
  constructor(props){
    super(props)
    this.state = {
      articles: [],
    }
  }
  
  componentDidMount(){
    fetch(...)
  }

  render() {
    const { id } = this.props.match.params;
    const { articles } = this.state;

    ...
    return (
      <>
        <div ref={node => this.node = node} />
        <div style={styles.postsWrapper}>
          {display}
        </div>
      </>
    )
  }
}

我心中有兩個疑問

  1.  什麼是 class ?
  2.  為什麼 React 需要 class ?
//藍圖
class Person {
  constructor(name) {
    this.name = name;
  }
}
//實體
const john = new Person('John');

什麼是 class ?

定義好物件的整體結構藍圖(blueprint),然後再用這個類別定義,以此來產生相同結構的多個的物件實例

為什麼我們使用 React 時需要 class ?

class Articles extends PureComponent {
  constructor(props){
    super(props)
    this.state = {
      articles: [],
    }
  }
  
  componentDidMount(){
    fetch(...)
  }

  render() {
    const { id } = this.props.match.params;
    const { articles } = this.state;

    ...
    return (
      <>
        <div ref={node => this.node = node} />
        <div style={styles.postsWrapper}>
          {display}
        </div>
      </>
    )
  }
}

因為可以使用 extends

繼承 React.Component

 

進而去進行 setState 或

life cylcle 的操作

去脈絡化?

Javascript 跟其他語言的差異

ES6 包裝了原本 JS 物件導向的方法
=> 讓 Consturctor 更簡潔、更易讀
=> 但本質上還是 Prototype-Based

Java 中要做 Class 間的繼承,得在定義 Class 時指定要繼承的父類別。


JavaScript 中則是以改變 Constructor 的 Prototype 來使用其他 Constructor 的 Method 。

Constructor

Constructor 是建構函式,可以用它產生擁有相同 Properties 的 Object (Instance)

function Person(name, age) {
  // properties
  this.name = name;
  this.age = age;
  // methods
  this.log = function () {
    console.log(this.name + ', age:' + this.age);
  }
}

var nick = new Person('nick', 18);
nick.log(); // nick, age:18
  
var peter = new Person('peter', 20);
peter.log(); // peter, age:20
  

Constructor

Instance

但可以注意到的是,當你

console.log(nick.log === peter.log) // false

雖然 nick 的 log 這個 function 跟 peter 的 log 這個 function 是在做同一件事

 

但其實還是佔用了兩份空間,意思就是他們其實是兩個不同的 function。

這時候 prototype 就派上用場啦

function Person(name, age) {
  this.name = name;
  this.age = age;
}
  
Person.prototype.log = function () {
  console.log(this.name + ', age:' + this.age);
}
  
var nick = new Person('nick', 18);
var peter = new Person('peter', 20);
  
console.log(nick.log === peter.log) // true
  
// 功能依舊跟之前一樣
nick.log(); // nick, age:18
peter.log(); // peter, age:20

但........ Instance 是怎麼找到 prototype 的 ?

是依靠每個物件裡都會有的 __proto__

阿拉丁?

__proto__ 係蝦米? 好像在哪看過

__proto__ 裡會寫此實體可以使用的函式

 

而函式的內容即是類別的 prototype提供的

  Object.prototype.playMajiang = function () {
    console.log('打麻摟');
  }
  console.log(Object.prototype === dailyData.__proto__) //true

Point() => constructor

redPoint => instance

__proto__ 不斷串起來的鍊,就叫做原型鍊。透過這一條原型鍊,就可以達成類似繼承的功能

參考資料

 

5/30 Javascript - prototype

By Jay Chou

5/30 Javascript - prototype

  • 331