每個構造函數都有一個原型對象(prototype),原型對象都包含一個指向構造函數的指針(constructor),而實例都包含一個指向原型的內部指針(__proto__)。javascript
emp1:java
function Foo(y){ this.y = y ; } Foo.prototype.x = 10; Foo.prototype.calculate = function(z){ return this.x+this.y+z; }; var b = new Foo(20); alert(b.calculate(30));
全部函數的默認原型都是Object的實例,所以默認原型內部都有一個指針,指向Object.prototype,這也正是全部自定義對象都會繼承toString()、valueOf()等方法的根本緣由。chrome
Foo的構造函數時Function 任何一個對象的__proto__都有值,由於每個對象都有構造函數。函數
如圖:this
函數是對象,對象又都是經過函數建立的。任何一個函數內都有prototype屬性。spa
在javascript中,一個對象就是任何無序鍵值對的集合,若是它不是一個主數據類型(undefined,null,boolean,number,or string),那它就是一個對象。firefox
false明明是一個主數據類型,false.__proto__也會返回一個值 。由於在代碼執行它會被強制轉化成一個對象(Boolean 基本包裝類型)。prototype
分步寫法:(具備實時性)設計
function a (){ this.age = 1; } a.prototype.str = 'ss'; var b = new a(); a.prototype.name='tom'; console.log(b.str);//ss console.log(b.name); //tom
字面量寫法:(會致使原型重寫) 指針
function a(){ this.name = 'w'; } a.prototype.str = 's'; var b = new a(); console.log(b.str); //s //字面量寫法 a.prototype = { x:1 }; //a原型重寫並無反映到a以前建立 的實例中 console.log(b.str); //s console.log(b.x);//undefined //a的原型反映到重寫後建立的實例中 var c = new a(); a.prototype.q = 3; console.log(c.x); //1 console.log(c.q); //3 console.log(c.str); //undefined
函數a的原型爲函數b的實例,函數a的實例就會繼承a和b的原型的全部方法和屬性。 見圖《JavaScript高級程序設計》p163
__proto__
本質上實際上是標準裏規定的[[prototype]]
屬性,本來是不可用 js 訪問的,後來(聽說標準裏又規定能夠)firefox 和 chrome 中把這個屬性命名爲__proto__
。後來ES
又添加了函數getPrototypeof
,這樣就能夠經過這個函數來訪問這個屬性,因此這個__proto__
如今不是標準的一部分。
而後,再說new
的建立過程,當執行new func()
的時候,執行過程以下:
一、首先建立一個新的對象,好比叫 obj
;
二、obj.[[prototype]] = func.prototype
;
三、令this=obj
,執行函數 func
;
四、若是 func
的返回值是一個對象,則 new
的返回值就是這個對象,不然返回值是 obj
<script type="text/javascript"> var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.__proto__ = animal; var tidy = new dog(); console.log(dog.price) //2000 console.log(tidy.price) // undefined </script>
constructor指的就是對象的構造函數 對象是由函數構造的
function Foo(){}; var foo = new Foo(); alert(foo.constructor);//Foo alert(Foo.constructor);//Function alert(Object.constructor);//Function alert(Function.constructor);//Function
由於Foo,Object,Function都是函數對象,又由於全部的函數對象都是Function這個函數對象構造出來,因此它們的constructor爲Function
prototype與constructor的關係
function Dog(){}
(Dog === Dog.prototype.constructor);//true
console.log(Dog.prototype.hasOwnProperty('constructor'));//true
function Animal(){}
function Person(){}
var person = new Person();
console.log(person.constructor); //Person
任何一個函數的原型都有constructor屬性
person是Person的實例,因此person繼承Person原型上的全部屬性和方法,Preson原型有constructor屬性並指向Preson,因此person有constructor屬性並指向Preson
深刻一點
function Animal(){} function Person(){} Person.prototype = new Animal(); var person = new Person(); alert(person.constructor); //Animal
如圖
圖中的虛線表示Person默認的prototype指向(只做參考的做用)。可是咱們將Person.prototype指向了new Animal。
還有