1、函數調用
調用一個函數將暫停當前函數的執行,傳遞控制權和參數給新函數。除了函數聲明時定義的形參,每個函數還接受兩個附加的參數:this和arguments(arguments並不是一個真正的數組,它擁有length屬性,但它缺少數組的所有方法)。參數this在面向對象編程中非常重要,它的值取決於調用的模式。
在js中一共有四種調用模式:方法調用模式、函數調用模式、構造器調用模式和apply調用模式。這些模式在如何初始化關鍵參數this上存在差異。arguments的個數取決於函數定義時候形參的個數,如果調用函數時,傳遞的形參與函數定義的參數個數不匹配不會導致運行錯誤,調用時傳遞的參數過多,
超出的參數會被忽略,如果過少,缺失的值被undefined代替。
2、方法調用模式
var myObj = { value:0, increment:function(val){ this.value += typeof val ==="number" ? val : 1;//this為myObj對象 } }; myObj.increment(); document.write(myObj.value);//1 myObj.increment(2); document.write(myObj.value);//3
方法可以使用this去訪問,所以它能從對象取值或修改該對象。this到對象的綁定發生在調用的時候。這個“超級”遲綁定使得函數可以對this高度復用。通過this可取得它們所屬對象的上下文的方法稱為公共方法。
3、函數調用模式
var name = "zhangsan";//aa變量加載到了window對象上 function test(){ function test1(){ document.write(this.name);//zhangsan,this為window對象 }; test1(); } test();
當函數以此模式調用時,this被綁定到全局對象。這是語言設計的一個錯誤。倘若語言設計正確,當內部函數被調用時,this應該仍然綁定到外部函數的this變量。這個設計錯誤的后果是方法不能利用內部函數來幫助它工作,因為內部函數的this被綁定了錯誤的值,所以不能共享該方法對對象的訪問權。
幸運的是,有一個很容易的解決方案:如果該方法定義一個變量並給它賦值為this,那么內部函數就可以通過那個變量訪問到this,按照約定,我給那個變量命令為that
//目的:使用add方法對數值進行相加 //給myObject增加一個double方法。 myObject.double = function(){ var that = this;//解決方法 var helper = function(){ that.value = add(that.value,that.value);//add方法為兩數字相加 }; helper();//以函數的形式調用helper }; //以方法模式調用double myObject.double(); document.write(myObject.getValue());//6,這樣helper方法可以使用this
4、構造器調用模式
對象實例調用原型中的方法時,該方法可以使用this訪問其構造函數內的屬性或方法。
//創建一個名為Quo的構造函數,它構造一個帶有status屬性的對象。 var Quo = function (str,name){ this.status = str; this.name = name; }; //給Quo的所有實例提供一個名為get_status的公共方法。 Quo.prototype.get_status = function(){ return this.status;//this能訪問到status }; Object.prototype.get_name = function(){ return this.name;//能訪問到name }; //構造一個Quo實例 var myQuo = new Quo("confused","zhangsan"); //confused,document.write()和document.writeln都是js向客戶端寫入的方法,writeln是以行方式輸出的,但並不是指頁面實際效果中的換行,即頁面的實際效果是沒有換行的。 document.writeln(myQuo.get_status()); document.write(myQuo.get_name());//zhangsan
5、Apply調用模式
apply方法讓我們構建一個參數數組並用其去調用函數。它也允許我們選擇this的值。
apply方法接受兩個參數,第一個是將被綁定給this的值,第二個就是一個參數數組。
var myStatus = { status:'A-OK' }; //myStatus並沒有繼承自Ouo.prototype。但我們可以在myStatus上調用get_status方法,盡管myStatus並沒有一個名為get_status的方法 var st = Quo.prototype.get_status.apply(myStatus);//A-OK var st1 = myQuo.get_status.apply(myStatus);//A-OK