JavaScript學習總結--建立對象(3_原型)

 當咱們建立一個函數時,這個函數都會有一個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

因此咱們能夠結合這兩個方法的結果來判斷某個屬性是否在原型中

待續

...

相關文章
相關標籤/搜索