在 JavaScript 原型繼承結構裏面,規範中用 [[Prototype]] 表示對象隱式的原型,在 JavaScript 中用 __proto__ 表示,而且在 Firefox 和 Chrome 瀏覽器中是能夠訪問獲得這個屬性的,可是 IE 下不行。全部 JavaScript 對象都有 __proto__ 屬性,但只有 Object.prototype.__proto__ 爲 null,前提是沒有在 Firefox 或者 Chrome 下修改過這個屬性。這個屬性指向它的原型對象。 至於顯示的原型,在 JavaScript 裏用 prototype 屬性表示。web
/** * 聲明構造函數Person,建立Person的實例p */ var Person = function () { }; var p = new Person(); //等價於: var p = {}; //初始化一個對象p p.__proto__ = Person.prototype; // Person.call(p); //初始化p
證實一下:瀏覽器
var Person = function () { }; var p = new Person(); p.__proto__ === Person.prototype; // true
每一個函數都有一個prototype屬性,這個屬性是指向一個對象的引用,這個對象稱爲原型對象,原型對象包含函數實例共享的方法和屬性,也就是說將函數用做構造函數調用(使用new操做符調用)的時候,新建立的對象會從原型對象上繼承屬性和方法。默認狀況下prototype屬性會默認得到一個constructor(構造函數)屬性,這個屬性是一個指向prototype屬性所在函數的指針,有些繞了啊,寫代碼、上圖! 函數
根據上圖能夠看出Person對象會自動得到prototyp屬性,而prototype也是一個對象,會自動得到一個constructor屬性,該屬性正是指向Person對象。spa
當調用構造函數建立一個實例的時候,實例內部將包含一個內部指針(不少瀏覽器這個指針名字爲__proto__)指向構造函數的prototype,這個鏈接存在於實例和構造函數的prototype之間,而不是實例與構造函數之間。prototype
function f1(){} var f2 = function(){} var f3 = new Function('str','console.log(str)'); f1 instanceof Function //true f2 instanceof Function //true f3 instanceof Function //true Object instanceof Function //true Function instanceof Function //true Object.__proto__ === Function.prototype //true Function.__proto__ === Function.prototype //true
f一、f二、f3爲函數,可是其實函數也是對象,是Function的實例。指針
Function , Object 都是函數引用,由Function建立出來,全部均有__proto__屬性,指向Function.prototype。code
總結orm
每個函數都有prototype這個顯示屬性,這個屬性是一個引用,指向一個對象,這個對象包含一個屬性constructor,指向prototype屬性所在的函數的指針。對象
每個實例都有一個__proto__這個隱藏屬性,這個屬性指向實例構造函數的prototype屬性。blog
當咱們訪問一個對象的屬性 時,若是這個對象內部不存在這個屬性,那麼他就會去__proto__裏找這個屬性,這個__proto__又會有本身的__proto__,因而就這樣 一直找下去,也就是咱們平時所說的原型鏈的概念。