JS的對象的原型

翻閱到之前的學習筆記,加上本身如今的理解,談一談JS的原型鏈。程序員

tips:本文有不少胡言亂語,若是你已經掌握js原型鏈,不建議閱讀本文,以避免被我誤導。編程

對象的原型究竟在哪裏?

function Person() {

}
let person = new Person();
複製代碼

當初我很不理解,person的原型是什麼? 不少教程就說:數組

person的原型是 person.__proto__bash

我又疑問,那Object的原型呢?編程語言

Object.__proto__函數

當初我真是特別崩潰。就好像,我問:老王的兒子是誰?有人回答:老王的兒子是老王.兒子學習

我指望的回答是相似於小李,小張的答案,而不是老王的兒子是老王.兒子這種間接的答案。ui

對象繼承

咱們知道其餘編程語言中的面對對象,每每都是基於類的面對對象。this

就好像:有人類的概念,而後咱們能夠建立一我的類的實例。spa

基於類的面對對象的代碼可能長這樣子:

class Human{
        
}
new p1 = new Human()
複製代碼

而後中國人的概念繼承自人類

class Chinese extend Human{
    
}
let c1 = new Chinese()
複製代碼

原型繼承

JS和基於類的繼承不一樣,JS是基於原型的。

可是在原型繼承中,就沒有人類,中國人類的概念了,取而代之的是一我的,一箇中國人的概念。

漢語中,咱們會說:李華是一我的

一我的的概念和奇特。 你能夠說小明是小明,小明是人類,可是很差說小明是「一我的」 就好像英文中,"a person" "the person" 的概念,當咱們跟說道小明的時候,咱們可能再說 "the person" 而不是 "a person",你找不到"a person" 由於你找到它的時候,他就是"the person"了。

JS中,除了四種基本類型,其餘一切都是對象。在js中函數也被定義爲對象。那是JS對象就要有原型,lihua的原型是什麼?你可能會這樣作:

一開始我也是這樣想的,在控制檯直接打印 lihua.__proto__,但其實否則,對象的原型是抽象的概念,他不存在於實體(js解釋器的內存中)。

lihua是什麼? lihua一我的,一我的具備的特徵李華都應該有。地球上有許多人,可是並不存在一我的這樣的實體。

有人可能會說:"我不是在控制檯打印了lihua.__proto__嗎,那麼在js解釋器的內存中,lihua__proto__指向的內存不就是一我的嗎?"

其實這是一種誤解,lihua並無一個叫__proto__的屬性。

這是控制檯爲了便於程序員調試,強行加上去的。控制檯用有形的方式告訴咱們無形的事物究竟有什麼特徵。你能夠說 lihua的原型的特徵是什麼,可是不能說 lihua的原型在某塊JS內存區。

一個

在我我的理解中,用一個的概念更容易理解JS的原型鏈.Object.prototype能夠理解爲一個對象。Function.prototype 能夠理解爲一個函數,而後一個函數的原型就是一個對象,因此 Function.prototype.__proto__ === Object.prototype

下面是我畫的原型鏈的圖

obj就是Object.prototype一個對象fun就是Function.prototype一個函數;以此類推。

咱們來捋一捋原型鏈。lihua原型是一我的一我的的原型是一個對象Array一個函數,因此他的原型是一個函數,同時他又是Functin的實例。一個Array的實例又是一個數組一個數組的原型又是一個對象

一個的概念來理解原型,是否是容易不少?

Object.create()

咱們知道,除了經過構造函數,咱們還能夠經過Object.create()來建立一個對象。

let a = {}
let b = Object.create(a)
複製代碼

這段代碼的意思就是建立一個對象b,並將b的原型指定爲a。

這是有人可能會說:我這不是找到b的原型了嗎?

b.__proto__ === a //true

其實我是這樣想的:

let obj = {
    name:"lihua"
}

let str = JSON.stringfiy(obj)
複製代碼

若是把obj,str理解爲JSON數據,他們表達的信息沒有任何區別。

上述代碼中,a既是JS解釋器內存中的對象,又能表達b的原型有怎樣的特徵。 語法上b.__proto__ === a //true,可是邏輯上b的原型是抽象的概念,a只是b的原型的一種表達。

好比下面三段代碼

function hi(){
    console.log("hi")
}
let h1 = new hi()


let lihua = {
    name:"lihua"
}
let l1 = Object.create(lihua)

let aperson = {
    eat:()=>{
        console.log(this.name + " is eatting")
    }
}
let lihuai = Object.create(aperson)

複製代碼

第一段代碼和第二段代碼沒有任何語法錯誤,可是邏輯上沒人會這麼寫,由於h1,l1沒有任何邏輯上的意義。

第三段代碼和第二段沒有什麼語法上的區別,可是他有邏輯意義。咱們建立了一個對象lihualihua的原型是一我的,而一我的有eat這個固有特徵,你們都知道這是什麼意義。等價於下面的代碼:

function Person(){}
Person.prototype.eat = ()=>{
    console.log(this.name + " is eatting")
}
複製代碼

結語

說了半天,就是想表達:不要單純從語法上理解JS的原型鏈,還要考慮其中的邏輯意義。對象和對象的原型之間的關係就想李華和一我的之間的關係。

相關文章
相關標籤/搜索