1. 程式人生 > 程式設計 >js建構函式constructor和原型prototype原理與用法例項分析

js建構函式constructor和原型prototype原理與用法例項分析

本文例項講述了js建構函式constructor和原型prototype原理與用法。分享給大家供大家參考,具體如下:

所有引用型別(函式,陣列,物件)都擁有__proto__屬性(隱式原型)

所有函式擁有prototype屬性(顯式原型)(僅限函式)

原型物件:擁有prototype屬性的物件,在定義函式時就被建立

__proto__,prototype和constructor

下面這三個屬性的定義非常重要,始終貫穿在原型中。

  • prototype:此屬性只有建構函式才有,它指向的是當前建構函式的原型物件
  • __proto__:此屬性是任何物件在建立時都會有的一個屬性,它指向了產生當前物件的建構函式的原型物件
    ,由於並非標準規定屬性,不要隨便去更改這個屬性的值,以免破壞原型鏈,但是可以藉助這個屬性來學習,所謂的原型鏈就是由__proto__連線而成的鏈。
  • constructor:此屬性只有原型物件才有,它預設指回prototype屬性所在的建構函式

建構函式的特點:

 a:建構函式的首字母必須大寫,用來區分於普通函式

 b:內部使用的this物件,來指向即將要生成的例項物件

 c:使用New來生成例項物件

function定義的物件有一個prototype屬性,使用new生成的物件就沒有這個prototype屬性(Person是一個物件)

Person是一個物件,它有一個prototype的原型屬性(因為所有的物件都一prototype原型!)prototype屬性有自己的prototype物件,而pototype物件肯定也有自己的construct(構造)屬性,construct屬性有自己的constructor(建構函式)物件,神奇的事情要發生了,這最後一個constructor物件就是我們構造出來的function函式本身

function Person(name){
 this.name=name;
 this.showMe=function(){
 alert(this.name)
 }
}
var one=new Person('js-yeluosen');
one.showMe();
console.log(one.prototype)//undefined
console.log(typeof Person.prototype)//Obiect
console.log(Person.prototype)
console.log(Person.prototype.constructor)

js建構函式constructor和原型prototype原理與用法例項分析

當呼叫某種方法或查詢某種屬性時,首先會在自身呼叫和查詢,如果自身並沒有該屬性或方法,則會去它的__proto__屬性中呼叫查詢,也就是它建構函式的prototype中呼叫查詢

當函式物件本身的屬性或方法與原型的屬性或方法同名的時候:

1、預設呼叫的是函式物件本身的屬性或方法.
2、通過原型增加的屬性或方法的確是存在的.
3、函式物件本身的屬性或方法的優先順序要高於原型的屬性或方法.

function Hero(){
 this.name='jiangyx'
}
Hero.prototype.name="yeluosen"
var mm=new Hero()
// 當呼叫某種方法或查詢某種屬性時,首先會在自身呼叫和查詢,如果自身並沒有該屬性或方法,則會去它的__proto__屬性中呼叫查詢,也就是它建構函式的prototype中呼叫查詢
alert(mm.name)//jiangyx
alert(mm.__proto__.name)//jiangyx
delete mm.name
alert(mm.name)//yeluosen

//建立建構函式
function Word(words){
  this.words = words;
}
Word.prototype = {
  alert(){
    alert(this.words);
  }
}
//建立例項
var w = new Word("hello world");
w.print = function(){
  console.log(this.words);
}
w.print(); //hello world
// 當呼叫某種方法或查詢某種屬性時,首先會在自身呼叫和查詢,如果自身並沒有該屬性或方法,則會去它的__proto__屬性中呼叫查詢,也就是它建構函式的prototype中呼叫查詢
// w本身沒有alert()方法,所以會去Word()的顯式原型中呼叫alert(),即例項繼承建構函式的方法。     
w.alert(); //hello world
// 例項w的隱式原型指向它建構函式的顯式原型,指向的意思是恆等於
// w.__proto__ === Word.prototype

print()方法是w例項本身具有的方法,所以w.print()列印hello world;alert()不屬於w例項的方法,屬於建構函式的方法,w.alert()也會列印hello world,因為例項繼承建構函式的方法。

例項w的隱式原型指向它建構函式的顯式原型,指向的意思是恆等於

w.__proto__ === Word.prototype

總結

1、prototype只有建構函式才有,指向建構函式的原型。
2、__proto__任何物件都有,指向產生當前物件的建構函式的原型。
3、constructor只有原型物件才有,預設指回prototype屬性所在的建構函式,使用原型鏈繼承之後,要給新的原型物件新增constructor屬性並指向建構函式。
4、任何物件都有產生自己的建構函式,包括建構函式自己。

感興趣的朋友可以使用線上HTML/CSS/JavaScript程式碼執行工具:http://tools.jb51.net/code/HtmlJsRun測試上述程式碼執行效果。

更多關於JavaScript相關內容感興趣的讀者可檢視本站專題:《javascript面向物件入門教程》、《JavaScript錯誤與除錯技巧總結》、《JavaScript資料結構與演算法技巧總結》、《JavaScript遍歷演算法與技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程式設計有所幫助。