建構函式就是初始化一個實例對象,而物件的prototype屬性是繼承一個實例物件。
建構子注意事項:
1.預設函數首字母大寫
2.建構函式並沒有顯示回傳任何東西。 new 操作符會自動建立給定的類型並返回他們,當呼叫建構函數時,new會自動建立this對象,而類型就是建構函數類型。
3.也可以在建構函式中顯示呼叫return.如果傳回的值是一個對象,它會取代新建立的物件實例返回。如果傳回的值是一個原始類型,它會被忽略,新建立的實例會被傳回。
function Person( name){ this.name =name; } var p1=new Person('John');
等同於:
function person(name ){ Object obj =new Object(); obj.name =name; return obj; } var p1= person("John");
4.因為建構函數也是函數,所以可以直接被調用,但是它的返回值為undefine,此時建構函數裡面的this物件等於全域this物件。 this.name其實就是要建立一個全域的變數name。在嚴格模式下,當你補透過new 呼叫Person建構函式會出現錯誤。
5.也可以在建構子中用Object.defineProperty()方法來幫助我們初始化:
function Person( name){ Object.defineProperty(this, "name"{ get :function(){ return name; }, set:function (newName){ name =newName; }, enumerable :true, //可枚举,默认为false configurable:true //可配置 }); } var p1=new Person('John');
6.在建構函式中使用原型物件
//比直接在构造函数中写的效率要高的多 Person.prototype.sayName= function(){ console.log(this.name); };
但如果方法比較多的話,大多人會採用更簡潔的方法:直接使用一個物件字面形式來取代原型對象,如下:
Person.prototype ={ sayName :function(){ console.log(this.name); }, toString :function(){ return "[Person "+ this.name+"]" ; } };
這種方式非常流行,因為你不用多次鍵入Person.prototype,但有一個副作用你一定要注意:
使用字面量形式改寫了原型物件改變了建構子的屬性,因此他指向Object而不是Person。這是因為原型物件具有一個constructor屬性,這是其他物件實例所沒有的。當一個函數被創建時,它的prototype屬性也被創建,且該原型物件的constructor屬性指向該函數。當使用物件字面量形式改寫原型物件時,其constructor屬性將被置為泛用物件Object.為了避免這一點,需要在改寫原型物件的時候手動重置constructor,如下:
Person.prototype ={ constructor :Person, sayName :function(){ console.log(this.name); }, toString :function(){ return "[Person "+ this.name+"]" ; } };
再次檢定:
p1.constructor===Person
true
p1.constructor===Object
false
p1 instanceof Person
true