標籤:方法調用 else 執行 fine cti parameter undefined div 參數
今天剛好周六沒事,又由於工作的原因導致早上醒來就睡不著,無聊之下,就想到了 js 的function調用問題。當然,網上也是對javascript的一些事情說得很透了,但我覺得還是有必要把自己的想法說出來,雖然並沒有什麼好了,閑話短說,現在開始js的function調用解析。最後再囉嗦一句,如果寫的有什麼不對或者不全的地方,還請多多指點。
好了,本文開始:
雖然瀏覽器是多線程的,但是瀏覽器中的js引擎是一個基於事件驅動的單線程運行模式,也就是說,JS引擎會只會順序的從工作清單中取任務。js中調用一個函數時,將暫停當前函數的執行,徹底控制權和參數給新的函數,除了傳遞形參(如果實際參數與形參個數不匹配,實際參數溢出,那麼在被調用的函數中不會顯示,但是可以通過arguments取出;實際少,那麼在被調用的函數中相應的參數為undefined),還會附加兩個參數,即this和arguments。this在物件導向編程中是非常重要的,它在js的函數調用中,決定了以什麼方式調用函數,說到這,我好像忘了說函數的幾種調用方式了。
函數調用大概有4種:
1.方法調用模式;
2.函數調用模式
3.構造器調用模式;
4.apply/call/bind調用模式
方法調用模式:當一個函數被儲存為一個對象的屬性時,我們稱之為方法,當調用這個方法的時候,this就會指向當前方法所在的對象;
var myObjectMethod = { method:function(isParameters){ if(isParameters){ return this.property="porpertyChange"; } else{ return this.property; } }, porperty:"startCall" } myObjectMethod.method();//myObjectMethod.porperty = "startCall"; myObjectMethod.method(true); // myObjectMethod.porperty = "porpertyChange";
方法的this指向了方法所在的對象,並且可以通過this去擷取/改變該對象中的屬性,this指向改變是在調用的的時候,可以通過this擷取該對象的方法稱為公用方法(public);
函數調用模式:當一個函數非一個對象的屬性時,那麼他被當作一個函數來調用,this會指向全域(window);
var myObjectFunction = { method: function(isParameters) { var myFunction = function(){ return this.property="call";//thsi -> window } return myFunction(); }, property: "startCall" } debugger window.property = "window.porperty "; myObjectFunction.method(); //myObjectFunction.porperty = "startCall"; window.property ="cal";
當然,可以通過函數的範圍/閉包來擷取myObjectFunction.property:
var myObjectFunction = { method: function(isParameters) { var that = this; var myFunction = function(){ //thsi -> window return that.property = "call";// that -> myObjectFunction } return myFunction(); }, property: "startCall" } debuggerc window.property = "window.porperty "; myObjectFunction.method(); //myObjectFunction.porperty = "call"; window.property ="window.porperty ";
構造器調用模式:繼承是OO語言中一個重要的特性和概念。許多的OO語言中都支援兩種繼承方式:介面繼承和實現繼承。而js是同故宮原型鏈的方式實現繼承的。通過new的方式調用,此時this會指向函數的prototype上
var myObjectFunction = { method: function(isParameters) { var myFunctionConstructor = function(){ } myFunctionConstructor.prototype.property = "myFunction.prototype.property"; return new myFunctionConstructor(); }, property: "startCall" } window.property = "window.porperty "; var result = myObjectFunction.method(); //result = myFunction.prototype; myObjectFunction.porperty = "startCall"; window.property ="window.porperty "; //result.property =myFunction.prototype.property
上面那個例子估計有點迷糊,沒有很好的體現出構造器調用模式
window.property = "window.prperty"; var method = function(val) { this.property = val;//this -> method.prototype } method.prototype.property = "method.prototype.property"; var myMethod = new method("val");//myMethod.property="val";window.property= "window.prperty";
希望這個例子,能讓大家明白一點;
apply/call/bind調用模式調用模式:
apply/call/bind 的調用都能改變this的指向,使this指向設定的對象。
var myObjectFunction = { method: function(a,b,c) { return this.property; }, property: "startCall" } var Object = { property: "ObjectCall" } var result = myObjectFunction.method.apply(Object,[1,2,3]); result = myObjectFunction.method.call(Object,4,5,6); var myFunction = myObjectFunction.method.bind(Object,7,8); myFunction(9);
apply/call/bind 的調用的區別:
1.apply/call調用立即執行,而bind是先綁定,需要手動去調用它;
2.apply傳遞的是一個數組,而call/bind是依次傳值;
3.bind能綁定傳遞的參數,也可以不綁定參數
好吧,函數的調用到這兒就寫完了,希望對大家有所協助,不再之處,還望海涵,謝謝。
我認知的javascript之函數調用