當咱們建立一個函數時,這個函數都會有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,這個對象包含了特定類型的全部實例共享的屬性和方法前端
就象這樣數組
仔細觀察咱們能夠發現,數組對象Array的prototype屬性指向一個對象,而這個對象包含了不少屬性和方法,其中就有咱們常見的length屬性,以及pop()、push()、shift()等方法函數
那麼也就是說,這些屬性和方法被定義在Array的prototype上,爲全部的實例對象(數組)共享this
因此咱們在定義數組以後就可使用這些屬性和方法,且每個數組都引用自這個原型上的屬性和方法,在原型上的屬性是共享的,因此實例化一個新數組只會隱含指向這個原型對象的指針(__proto__)而不是徹底複製一份spa
因此咱們得知prototype
var aArr=new Array(); console.log(aArr.__proto__==Array.prototype);
在JavaScript內置對象Array上有一個prototype屬性,指向了包含對全部數組共享屬性和方法的一個對象,而經過Array實例化一個新數組,這個數組也有一個__proto__屬性,也指向這個對象,這個對象在JavaScript中就叫作原型設計
那麼一樣的,Date對象也會有一個prototype屬性,指向了包含對全部日期對象共享屬性和方法的一個對象,經過Date對象實例化的一個日期對象也會有一個__proto__屬性指向他們的原型指針
前面咱們說到,構造函數封裝對象的本質就是模仿JavaScript的內置對象,那麼既然內置對象共享的屬性和方法都存放在這個prototype上,咱們本身建立的對象也能夠嗎?code
上一節咱們有一段代碼是這樣的對象
person_01.sayName==person_02.sayName; //false
那麼咱們使用原型來建立對象看看會不會有什麼不一樣
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; } Person.prototype.sayName=function(){ //這樣能夠把方法寫在原型上 console.log(this.name); } //書上會繞一大個彎先把全部屬性和方法都寫在原型上,再講某些屬性不能共享之類的,這裏跳過 var person_01=new Person("Sakura",22,"前端開發"); var person_02=new Person("Misaka",20,"網頁設計");
這時咱們再來看看兩個實例化對象的sayName方法是否是相等
person_01.sayName==person_02.sayName; //true //同時能夠得知 person_01.__proto__==Person.prototype; //true person_01.__proto__==person_02.__proto__; //true
同時在prototype對象上也有一個可有可無的屬性constructor屬性,這個屬性指向原型所屬的構造函數(能夠認爲是指向它所屬的類型)
console.log(Person.prototype.constructor); /* function Person(name,age,job){ this.name=name; this.age=age; this.job=job; } */ //由於實例化對象的__proto__屬性也指向原型對象,那麼 console.log(person_01.__proto__.constructor==Person.prototype.constructor); //true
JavaScript實例化對象在調用屬性時,首先會在構造函數內部查找屬性,若是有則用這個屬性,若是沒有則在原型上查找
咱們知道person_01的constructor屬性實際實在它的原型上,構造函數內部找不到constructor屬性,因此它會繼續往上在原型中查找,因此
console.log(person_01.constructor==Person.prototype.constructor);
如何判斷一個屬性或方法在原型仍是在構造函數內部(實例屬性)呢?
咱們使用hasOwnProperty方法
console.log(person_01.hasOwnProperty("name")); //true
hasOwnProperty方法其實是判斷屬性是否在構造函數內,若是在構造函數內則返回true;若是在原型中則返回false
同時有一個in操做符,能夠判斷某個對象是否包含某一個屬性,不管在原型仍是在構造函數中
console.log("name" in person_01); //true
因此咱們能夠結合這兩個方法的結果來判斷某個屬性是否在原型中
待續
...