簡單說說JS的prototype

2018-11-07

JS是被很多大佬差評的“迷の編程語言”,跟著差評莫不如深入的了解一下。

納入自己的豪華工具箱,等到有必要的時候拿出來用。

不過項目的開發推進像小團隊的話JS就這樣簡簡單單的就好。

一點廢話

  • 在ES6提供了class但只能看做是一個語法糖;
  • Java有直接的,(Class,對象的模板)和對象實例,JS傻傻木有;
  • 但是JS是通過構造函數原型鏈來實現這一切的;

接下來請讓我來bb這一切 / w \

一種簡單的開始

1
2
3
4
5
6
7
8
9
10
11
12
function Test(){
this.name = "99"
}
Test.prototype.getName = function(){
return this.name
}

var a = new Test()
var b = new Test()
console.log(a.getName()) //99
console.log(b.getName()) //99
console.log(a.getName === b.getName)//true

####構造函數

構造函數長這樣子:

1
2
3
function Test(name){
this.name = name
}

有了語法糖其實也可以長成這樣子:

1
2
3
4
5
6
7
8
class Human{
constructor(name){
this.name = name
}
getName(){
return this.name
}
}

別瞎想:不可以是這個樣子,為啥?反正我試了不行:(你不了解這個為啥看這篇?)

1
2
3
4
5
var Test = {
constructor: (name) => {
this.name = name
}
}

總之構造函數是生成對象的時候的一系列操作(根據規範”類名稱“、”構造函數“首字母要大寫)

構造函數缺點 == prototype的用處

對象中的屬性是不共享的!

1
2
3
4
5
//根據「構造函數」章節中的示例2
let jack = new Human("jack")
let mike = new Human("Mike")
console.log(jack.getName === mike.getName)
//> false

於是這樣就可以共享了

1
2
3
4
5
6
7
8
9
10
11
12
13
class Human{
constructor(name){
this.name = name
}
}
Human.prototype.getName = function(){
return this.name
}

let jack = new Human("jack")
let mike = new Human("Mike")
console.log(jack.getName === mike.getName)
//> true

畫出重點姿勢

  • JS數據類型除了nullundefined 其實都是對象(Objecy)

  • 每個對象繼承另外一個對象,被繼承的稱為原型對象,最終的原型對象是null

  • prototype對於構造函數來說屬性,對於對象實例指向其原型對象

  • 原型對象和其原型對象的關係形成了一個鏈;

    1
    A->B->C->D->...->null
  • 原型對象屬性,不是對象實例屬性

  • 對象實例屬性繼承構造函數定義的屬性構造函數通過this指向對象實例自己;

  • 對象實例本質來自構造函數構造函數變卦則對象實例也變;

誰是老祖宗?是null耶!

這個一定是有必要說一下的:這是一個簡單的原型鏈的“末端”。

1
2
console.log(Object.getPrototypeOf(Object.prototype))
//輸出:null
  • 注意向上”找祖宗“的過程是有一定開銷的,注意權衡(就是使用prototype是有一定的開銷的);
  • 找屬性/方法,向上一層一層找,到頂層找不到會輸出undefined

以上內容知道就好,不用背下來,反正考試不考你=~=

##一點小的總結

  1. prototype 的用途
  2. prototype 原型鏈

總之,它很簡單,先了解他是做什麼的(對,以上兩種);

然後知道:大家都是基於他加了一些東西,變成了另一個對象;


Kommentare: