完全搞懂Function,Object,__proto__,prototype之間的關係

寫在開篇以前:記錄學習點滴,若有錯誤與補充,但願你們積極指正。javascript

有4個規則必定要記住,以下java

  • javascript中一切皆對象,函數也屬於對象。
  • 全部對象都含有__proto__。
  • 只有函數纔有prototype。
  • 全部函數的默認原型都是Object的實例。

咱們來看一下demobash

var o = {};
    o.__proto__ === Object.prototype  //true
    o instanceof Object      //true
    o instanceof Function    //false
    
    var o = Object();
    o.__proto__ === Object.prototype  //true
    o instanceof Object      //true
    o instanceof Function    //false
    
    var o = new Object();
    o.__proto__ === Object.prototype  //true
    o instanceof Object      //true
    o instanceof Function    //false
    
    function Fn(){}
    var fn = new Fn();
    fn.__proto__ === Fn.prototype;
    
    fn instanceof Fn        //true
    fn instanceof Object    //true
    fn instanceof Function  //false

複製代碼

js中一切皆對象,函數也是對象的一種,姑且叫作函數對象。那麼FunctionObject是什麼關係呢。函數

  • 函數對象都是由Function函數生成的,看下例
function fn(){}
    
    fn.__proto__ === Function.prototype  //true
    fn instanceof Function  //true
    fn instanceof Object    //true
    
複製代碼

能夠看出當把函數當成對象的時候,函數也有__proto__屬性,而且生成它的函數就是Function,那麼Function本身呢,由於Function自己也是函數,函數是由Function生成的,那麼看下例。學習

Function.__proto__ === Function.prototype  //true
複製代碼
  • Object函數也是一個函數對象,也是由Function生成的,那麼看下例
Object.__proto__ === Function.prototype  //true
複製代碼
  • 對通常函數來講,prototype是什麼呢?以function fn(){}爲例子
    看看 fn.prototype的屬性等於什麼呢
fn.prototype.__proto__ === Object.prototype  //true
    fn.prototype.constructor === fn  //true
複製代碼

fn.prototype含有__proto__constructor兩個屬性,__proto__屬性指向Object.prototype,那麼通常函數的prototype是由Object函數生成的spa

  • 特殊函數 ObjectFunction

先看看Object.prototypeprototype

能夠看出Objectprototype的也是一個object類型的對象,可是和通常函數不同的對方是,他的prototype多出了不少其餘的方法,這些是Javascript系統默認的方法。可是好像沒有__proto__屬性啊,咱們把Object.prototype.__proto__打出來看看3d

這就是Object函數不同的地方了,Object.prototype.__proto__ === null,這就是Javescript原型鏈的終點了。那爲何是這個樣子呢?code

typeof Object.prototye === 'object',說明他是一個object類型的對象,若是他是由Object函數生成的,那麼Object.prototype.__proto__ === Object.prototype。那麼Object.prototype.__proto__指向自身,那麼以__proto__屬性構成的原型鏈將沒有終點了,因此爲了讓原型鏈有終點。Javascript規定,Object.prototype.__proto__ === nullcdn

那麼Function又是什麼狀況呢。

能夠看出Function屬性的prototype是一個 "function"類型的對象,而不像其餘的對象是 "object"對象,那麼既然是對象,那也是有__proto__屬性的,那麼 Function.prototype.__proto__是什麼呢

哇哦,看起來和Object.prototype好像啊,那麼試一下

那麼這又是爲何呢?

通常而言,一個"function"類型的對象,應該是由Function函數生成的,也就是Function.prototype.__proto__ === Function.prototype纔對,若是是這樣的話,也就出現了跟Object同樣的問題,一直循環利用,沒有盡頭。因此Javascript規定,Function.prototype.__proto__ === Object.prototype,Object.prototype.__proto__ === null,是原型鏈有終點。也就是在原型鏈的終點處有2個特殊狀況。

總結如下

  • 函數含有__proto__prototype屬性,__proto__指向Function.prototype,prototype指向Object.prototype,以Array函數爲例

  • 全部的類型的[[Prototype]]特性,即 __proto__屬性均指向的是 Function.prototype,同時 Function.prototype[[Prototype]]特性,即 __proto__屬性又指向了 Object.prototypeObject.prototype__proto__又指向null,即原型鏈的終點。

下面一些題目,你們分析看看

function fn(){}
 var o = {}
 var o1 = new Object();
 
 typeof fn     //"function"
 typeof fn.prototype   //"object"
 typeof fn.__proto__   //"function"  
 fn.prototype.__proto__ === Object.prototype  //true   全部函數的默認原型都是Object的實例
 fn.__proto__ === Function.prototype          //true   全部函數都是Function生成的
 
 fn instanceof Function  //true  fn是Function的實例
 fn instanceof Object    //true  fn也是Object的實例

 
 typeof o  //"object"
 typeof o.prototype  // "undefined"  由於只有函數纔有prototype
 typeof o.__proto__  // "object"
 o.__proto__.__proto__ === null   //true
 
 o instanceof Object   // true o是Object的實例
複製代碼

這篇文章寫的有些亂,後面再調整吧

相關文章
相關標籤/搜索