你真的知道js的原型鏈嗎??

9315l發表於2020-04-06

在去了解原型鏈之前,一定要先搞清楚兩個概念,一個是prototype,一個__proto__。耐心往下看哦

1.prototype

    首先什麼是prototype?prototype是函式的一個屬性,它是一個物件,裡面含有兩個屬性  constructor,__proto__,分別是什麼呢??如下圖,constructor是一個構造器,它指向自身,而__proto__指向的是物件

    記住:一切物件的根源 - Object.prototype

你真的知道js的原型鏈嗎??

2.__proto__

     __proto__是物件(出去null)所擁有的一個屬性,它指向的構造這個函式的原型物件(prototype),取個栗子

function a(){}
console.log(a.__proto__ === Function.prototype)   //true複製程式碼

      應該會有人會問,Object的

console.log(Object.prototype.__proto__ === null) //true
複製程式碼


3.原型鏈

   怎麼解釋原型鏈,其實需要靠大家去理解

   寫一小段簡單的程式碼,在進行解釋

function Person(){}
let p1 = new Persion()複製程式碼

    1.每個函式(通常指建構函式,如Person)都有一個屬性:prototype

    2.prototype是一個物件, 裡面有constructor , __proto__ 隱式原型

    3.建構函式的原型物件指向當前建構函式 Person.prototype.constructor === Person  

    4.例項物件的隱式原型指向建構函式的顯示原型 

               p1.__proto__ === Person.prototype 

    5.在建構函式顯示原型中新增的方法,所有的例項物件共享 

    6.訪問屬性和方法,是基於原型連進行訪問 在當前的例項物件去找--》建構函式的原型 ==》.... =》 Object的原型 

      

   光看這幾句話會很乾,可以看看下面的例子

    

4.簡單的原型鏈的題及其解釋

        var F = function(){}
        F.prototype.b = function (){            
          console.log('b()');}       
        Function.prototype.c = function () {    
          console.log('c()');}       
        Object.prototype.a = function () {      
          console.log('a()')   
        };       
        var f = new F();      
        F.a();      
        F.b();     
        F.c();         
        f.a();        
        f.b();      
        f.c();  複製程式碼

  這道題完全就是和原型相關,如果你能準確的說出答案,那麼原型和原型鏈的理解基本就是明白的了,做這道題的關鍵需要分清楚原型鏈的訪問(例項物件直接訪問建構函式的顯示原型的函式)

  畫一張圖就能很清楚的看出答案,話不多少,看圖

你真的知道js的原型鏈嗎??

看完圖之後,可以看出原型鏈分為兩條 - 一條是紅色,一條是綠色,原型鏈上的方法,例項物件都是可以訪問的

 F.b(),報錯,訪問F的b方法,應該為F.prototype.b(),記住一句就是例項物件可以直接訪問建構函式顯示原型的方法

 f.c(), 報錯,c並不是在f的原型鏈上面,而是在F的原型鏈上


5.Object和Function之間的關係

  第一,萬事萬物皆物件   

 console.log(Function.prototype.__proto__ === Object.prototype)  //true 
 console.log(Number.prototype.__proto__ === Object.prototype)   //true複製程式碼

  然後,js的所有類都是Function的例項,也是Object的派生類,Object物件直接繼承Function物件

 console.log(Object.constructor === Funciton)  //true
 console.log(Object instanceof Function) //true
 console.log(Function instanceof Object)//true 
 console.log(Object.__proto__  === Function.__proto__) //true       
 console.log(Object.__proto__ === Function.prototype); //true 
 console.log(Function.__proto__ === Function.prototype); //true複製程式碼

也就是說可以理解為物件其實也是由函式構造,Object其實也是個函式,而任何函式都是Function的例項物件(Object.__proto__ === Function.prototype),而函式自己構造了自己(Function.__proto__ === Function.prototype),也來看圖理解

你真的知道js的原型鏈嗎??

但是,敲黑板,不要進入一個誤區,如果說一切物件都能訪問到Object的prototype裡面的方法,像hasOwnProperty,toString,valueOf,toLocaleString等等,那是不是物件都可以訪問到在函式原型的方法,答案是,no. 原因又回到了原型鏈,大家不要進入誤區,值得注意的是,原型鏈的指向,最後指向了Object.prototype而不是Object.__proto__,Object.prototype.__proto__ === null


所以原型鏈只需要要死死的記住二句話就行了,1.函式的例項物件的隱式原型(__proto__)指向的建構函式的原型物件(prototype),2.所有的最後都指向了物件的顯示原型(prototype)


哈哈,終於寫完了

你真的知道js的原型鏈嗎??


相關文章