js:函數的調用

什麼是函數?
在js中函數是對象。

invocation(調用)

調用一個函數時,函數接受兩個附加的參數:this和arguments。參數this的初始化方式取決於調用的模式。一共有四種調用模式:

方法調用模式(the method invocation pattern)又稱爲隱式綁定

當一個函數被保存爲一個對象的屬性時,被稱爲‘方法’。當一個方法被調用時,this被綁定到該對象。

function foo() {      console.log( this.a ); } 
 
var obj = {      a: 2,     foo: foo  }; 
 
obj.foo(); // 2

對象屬性引用鏈中只有最頂層或者說最後一層會影響調用位置。舉例來說:

function foo() {      console.log( this.a ); } 
 
var obj2 = {      a: 42,     foo: foo  }; 
 
var obj1 = {      a: 2,     obj2: obj2  }; 
 
obj1.obj2.foo(); // 42

tips:隱式丟失:

function foo() {      console.log( this.a ); } 
 
var obj = {      a: 2,     foo: foo  }; 
 
var bar = obj.foo; // 函數別名! 
var a = "oops, global"; // a 是全局對象的屬性 
 
bar(); // "oops, global

這時候的bar只是引用了foo函數本身,因此此時的 bar() 其實是一個不帶任何修飾的函數調用,因此應用了默認綁定。

函數調用模式(the function invocation pattern)又稱爲 默認調用

當函數並未一個對象的屬性時,它被當作一個函數來調用。

function foo() {
      console.log( this.a ); 
}
var a = 2;  
foo(); // 2 
 

函數調用時應用了 this 的默認綁定,因此 this 指向全局對象。雖然 this 的綁定規則完全取決於調用位置,但是隻 有 foo() 運行在非 strict mode 下時,默認綁定才能綁定到全局對象

function foo() {      "use strict"; 
 
    console.log( this.a );  } 
 
var a = 2; 
 
foo(); // TypeError: this is undefine

構造器調用模式

如果函數傾向於和 new 關鍵詞一塊使用,則我們稱這個函數是 構造函數。 在函數內部,this 指向新創建的對象。

var Quo=function (string){
   this.status=string;
}
//給Quo的所有實例提供一個名爲get_status的公共方法
Quo.prototype.get_status=function(){
return this.status;
};
var myQuo=new Quo('confused');
document.writeln(myQuo.get_status());//confused

or

function foo(a) {      this.a = a; }  
 
var bar = new foo(2); console.log( bar.a ); // 2

apply or call 調用模式(顯式綁定)

這兩個方法是如何工作的呢?它們的第一個參數是一個對象,它們會把這個對象綁定到 this,接着在調用函數時指定這個 this。因爲你可以直接指定 this 的綁定對象,因此我 們稱之爲顯式綁定。

function foo() {      console.log( this.a ); } 
 
var obj = {      a:2 }; 
 
foo.call( obj ); // 2

從 this 綁定的角度來說,call(…) 和 apply(…) 是一樣的,它們的區別體現 在其他的參數上,但是現在我們不用考慮這些。

總結:

  1. 函數是否在 new 中調用(new 綁定)?如果是的話 this 綁定的是新創建的對象。 var bar = new foo()
  2. 函數是否通過 call、apply(顯式綁定)或者硬綁定調用?如果是的話,this 綁定的是 指定的對象。 var bar = foo.call(obj2)
  3. 函數是否在某個上下文對象中調用(隱式綁定)?如果是的話,this 綁定的是那個上 下文對象。 var bar = obj1.foo()
  4. 如果都不是的話,使用默認綁定。如果在嚴格模式下,就綁定到 undefined,否則綁定到 全局對象。 var bar = foo()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章