JavaScript 函式四種呼叫模式
阿新 • • 發佈:2019-01-25
函式有四種形態
-> 函式形態 -> 方法形態 -> 構造器形態 -> 上下文形態(call, apply)函式的四種呼叫模式
所有的 this 都是由當前函式決定,最終都是由函式的四種呼叫模式決定的。① 函式呼叫模式,只會執行一段程式碼,同時函式中的 this 是全域性物件 window;返回值由return語句決定,如果沒有return語句就表示沒有返回值
function f1(){ console.log(this); } f1();//window function f2(){ return function(){ console.log(this); } } var f2n=f2(); f2n();//this——>window,這也是一次函式呼叫模式 function f3(){ f3n();//函式呼叫模式——————>window function f3n(){ console.log(this); } } f3();// window
② 方法呼叫模式,只會執行一段程式碼,同時方法中的 this 是方法的所有者,即當前的例項物件;返回值由 return 語句決定
//程式碼1: var obj={ age:10, say:function(){ console.log(this.age); } }; obj.say();//方法呼叫模式 //程式碼2: function f1(){ console.log(this); } var obj2={ s1:f1//將f1函式賦值給obj2.s1屬性 }; obj2.s1();//方法呼叫模式——>this:obj2 //程式碼3: var obj3={ age:10, s1:function(){ console.log(this.age); } }; var obj4={ age:20, s2:obj3.s1//將obj3.s1函式賦值給s2屬性 }; obj4.s2();//方法呼叫模式:this——>obj4
③ 構造器呼叫模式,會用來建立一個物件,還是執行一段程式碼,this 表示當前物件 返回值: a. 沒有手動新增返回值,預設返回 this b. 返回了一個基本資料型別(number / boolean / string / null / undefined),最終返回 this c. 返回了一個複雜資料型別(物件),最終返回該物件
//程式碼1: function Person(){ this.age=20; this.name="張三"; console.log(this); } //建構函式呼叫模式: var p1=new Person(); //程式碼2; function P2(){ this.age=18; return "abc"; } var p2=new P2();//p2.age=18 //程式碼3: function P3(){ this.age=10; return {}; } var p3=new P3();//p3.age:undefined console.log("p3.age"); console.log(p3.age); //程式碼4: function P4(){ this.age=10; return [1,3,5]; } var p4=new P4();//p4.age:undefined console.log("p4.age"); console.log(p4.age);
④ 上下文呼叫模式,可以用引數來控制 this 的含義 語法: 函式.call(物件,引數列表) 函式.apply(物件,引數陣列) call 和 apply 除了引數不同,功能完全相同 this : a. 傳遞一個 null / undefined ,this 指向 window
b. 傳遞一個 數字 / 字串 / 布林值,this 指向 對應的基本包裝型別的物件(Number / String / Boolean)
c. 傳遞一個 物件:this 指向該物件 返回值:由 return 語句決定
例如呼叫 函式 func 需要兩個引數 func( 1, 2 ) 那麼使用上下文呼叫的語法是 func.call(obj, 1, 2); func.apply(obj, [1, 2]); apply 方法就是為了處理偽陣列 借用函式呼叫 p.sayHello => p.sayHello.call(p) p.sayHello.apply(p)
function f1(){
console.log(this);
}
//上下文模式
f1.call(null);//window
f1.call(undefined);//window
f1.call(1);//Number的例項
f1.call("abc");//String的例項
f1.call(true);//Boolean的例項
var s1="abc";
console.log(s1.length);//3
console.log(s1[0]);//"a"
//程式碼內部建立了字串所對應的String建構函式的例項
//{0:"a",1:"b",2:"c",length:3}
//程式碼執行完畢之後,就會把這個例項給銷燬
練習題1:
function f1(){
this.length=5;
return function(a,b,c){
this.length=10;
return [1,3,5];
}
}
//建構函式呼叫模式:
var r1=new f1();//r1是函式
console.log(r1.length);//任何函式都有一個length屬性表示形參的個數:3
//函式呼叫模式
var r2=r1();//r2:[1,3,5]
console.log(r2.length);//3
//建構函式呼叫模式
var r3=new r1();//r3:[1,3,5]
console.log(r3.length);//3
練習題2:
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function (f) {
f();//f變數的值是fn函式,但是這裡是函式呼叫模式--->this:window————>window.length:10
arguments[0]();//方法呼叫模式,this:arguments——>arguments.length:2
}
}
obj.method(fn, 1);
var o1={
0:function(){
},
say:function(){
}
};
o1[0]();
//o1.0();//錯誤
o1.say();
o1["say"]();