首先,先介紹一個今天的主角:proto(隱式原型)與prototype(顯式原型)javascript
prototype(顯式原型)
在每個函數(請注意是函數)建立以後都會有一個叫prototype的屬性,這個屬性指向的是函數的原型對象。java
__proto__(隱式原型)
javascript 中任意對象都具備一個內置屬性,在ES5以前並無標準的方法訪問這個屬性,可是在絕大多數瀏覽器中都支持經過__proto__來訪問這個屬性,咱們叫他隱式原型瀏覽器
首先咱們來看一個例子:函數
function Foo(){} var foo = new Foo(); foo.__proto__ === Foo.prototype; //=>true
由上面咱們能夠看出函數foo的隱式原型指向其構造函數的顯式原型.this
經過這個咱們能得出一個這樣的結論麼:
某對象(萬物皆對象).__proto__ === 其構造函數.prototype麼,
答案是否認的,咱們來看如下例子:prototype
let obj = {name: 'zarr'}; let sonObj = Object.create(obj); console.log(sonObj.name); //=>zarr console.log(sonObj.__proto__ === obj.prototype) //=>false console.log(sonObj.__proto__ === obj) //=>true
ok,咱們再看一個例子code
var Obj = { a: 13 }; var obj = Object.create(Obj); console.log(obj.a); //=>13 console.log(obj.__proto__ === Obj) //=>true var Func = function () { this.a = 'ds'; } var func = Object.create(Func); console.log(func.__proto__ === Func.prototype) //=>false console.log(func.__proto__ === Func) //=>true console.log(func.a) //undefined
不是說一個對象的隱式原型等於起構造函數的原型? 爲何這個時候又等於這個構造函數了?
這就要分析一下Object.create的實現了,其實實現起來也不難,你們看下面對象
Object.create = function(obj){ function f() {} f.prototype = obj; return new f(); }
這下明朗了, 經過Object.create構造出的對象其實仍是new出來的對象,好比上例的var func = Object.create(Func); func.__proto__ === f.prototype === Func,
func.__proto__ === f.prototype這個仍是成立的,可是因爲函數f在調用完Object.create方法以後就被銷燬了,因此只有func.__proto__ === Func。ip
ok,最後總結一下
1.對象有屬性__proto__,指向該對象的構造函數的原型對象。
2.方法除了有屬性__proto__,還有屬性prototype,prototype指向該方法的原型對象。原型