1.this對象是在運行時基于函數的執行環境綁定的:
(即函數可能在全局里運行,那么this指向全局對象,也可能在某個對象里運行,那么this指向那個對象。this的值是可以動態的改變的)。構造函數創建不同的實例的時候,this指向不同的新對象。當使用new關鍵字聲明,this指向新建對象。
2.call,apply是函數的方法(非繼承而來):function.call(thisobj,args 對象或array實例),apply里面是agrs數組。用call/apply可以動態的改變this 值。即call和apply
擴展:每個函數都包含兩個屬性 ?length(命名參數個數)和prototype
3.將Person.prototype設置為等于一個以對象字面量形式創建的新對象。相當于重寫了prototype對象。因為創建一個函數時,會同時創建一個prototype對象,這個對象會自動獲得一個constructor屬性。所以重寫prototype對象時,constructor屬性會指向Object構造函數,而不會指向Person構造函數了。可以手動創建constructor屬性。constructor:Person
4.
function Animal(){
? ? var aaa="ggg" ?//(1)
? ? this.aaa="zheng";(2)
? ? this.bb="si"
? ? this.jjj=function(){
? ? ? ? return aaa;
? ? ?}
}
Animal.prototype.aaa="haha"
var cat=new Animal()
console.log(cat.jjj()) ? //"ggg" ?不會查找this里面的
重點:首先要改為return this.aaa,如果刪掉(1), 結果為“zheng”,刪掉(2)結果為“haha”
console.log(cat.aaa) ?//"zheng" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
function Animal(){
this.bb="si"
}
var cat=new Animal() ? //<3>
Animal.prototype={
? ? constructor:Animal,
? ? aaa:"haha",
? ? jjj:function(){
? ? return this.aaa;
? ? }
//<4>
}
console.log(cat.jjj()) ? 結果:“haha”
重寫原型對象的問題:如果將<3>寫在<4>處,那么就報錯,因為重寫了后,切斷了現有原型與實例的聯系,引用的仍是之前的原型。
function Animal(){
this.aaa="ff" ? <5>
var aaa="nn"
this.bb="si"
}
var cat=new Animal()
Animal.prototype.aaa="haha";
Animal.prototype.jjj=function(){
return aaa;
}
console.log(cat.jjj()) ? ? //error報錯了
原型對象里面的方法找不到 var的 aaa? 因為不在一個作用域里面。要變成return this.aaa;? 則訪問到"ff",如果去掉<5>,則訪問到“haha”。可以想象成帶this的屬性和方法存儲了一份在新實例里面,找不到才去prototype里面找。
5.組合使用構造函數模式和原型模式
1)構造函數模式用于定義實例屬性 ?==》每個新實例都會有自己的一份實例屬性的副本。(通過this去copy)
2)原型模式