JavaScript 函數調用的四種方式與區別

  最近出了一些事情,好久沒有寫博客了,再次拿起也不知道要寫什麼,偶然閱讀到一篇文章。本篇短文大部份內容出自《JavaScript語言精粹》一書,有興趣的同窗能夠去購買閱讀,很棒的一本書,是js大師 道格拉斯·克羅克福德 的做品,不適合初學者。javascript

  調用一個函數時,會暫停當前函數的執行,傳遞控制權和參數給新函數(被調用的函數)。除了被調用的函數聲明時的形參,每一個函數還接收兩個附加的參數:this和arguments。參數this在面向對象編程中很是重要,它的值取決於調用的模式。在JavaScript中函數有4種調用模式:方法調用模式、函數調用模式、構造器調用模式和apply(call)調用模式。這些調用模式在如何初始化this上存在差別。java

  

  方法調用模式編程

  當一個函數被保存爲對象的一個屬性時,咱們稱它爲一個方法。當一個對象的方法被調用時,this被綁定到調用方法的對象。數組

var myObj = {
	name : "MT",
	setName : function(name){
		this.name = name;
	}
};

myObj.setName("哀木涕");
console.log(myObj.name);	//"哀木涕"

myObj.setName("小德");
console.log(myObj.name);	//小德

  方法可使用this訪問本身所屬的對象,因此它能從對象中取值或對對象進行修改。this和對象的綁定發生在方法調用的時候。這個「超級」延遲綁定(vary late binding)使得函數能夠對this高度複用。經過this能夠取得它們所屬對象的上下文方法稱爲公共方法(public method)。app

 

 函數調用模式編程語言

  當一函數並不是一個對象的屬性時,那麼它就是被當作一個函數來調用的:函數

var sum = add(1,2);    //sum的值爲3。

  以此模式調用函數時,this被綁定到全局對象。這是語言設計上的一個錯誤。假若語言設計正確,那麼當內部函數被調用時,this應該仍然綁定到外部函數的this變量。這個設計錯誤的後果就是方法不能利用內部函數來幫助它工做,由於內部函數的this被綁定了錯誤的值(全局對象),因此不能共享該方法對對象的訪問權。幸運的是,有一個很容易的解決方案:若是一個對象的方法定義了一個變量並將this賦值給它,那麼內部函數就能夠經過那個變量訪問到外部方法調用的對象。按照約定,咱們把那個變量命名爲that:this

myObj.changeName = function(){
	var that = this;	//解決方法
	
	var change = function(){
		that.name = "change" + that.name;
	}
	
	change();	//以函數的方式調用change;
}

//以方法的形式調用changeName。
myObj.changeName();
console.log(myObj.name);

  

 構造器調用模式spa

  JavaScript是一門基於原型繼承的語言。這意味着對象能夠直接從其餘對象繼承屬性。該語言是無類型的。prototype

  若是在一個函數前面帶上 new 關鍵字來調用,那麼背地裏將會建立一個鏈接到該函數的prototype成員的新對象,同時this會被綁定到那個新對象上。

  new 前綴也會改變return 語句的行爲,若是return 的值是對象,那麼將會將這個對象返回,不然將返回默認建立的新對象。

//建立一個名爲Person的構造器函數。它構造一個帶有name屬性的對象。
function Person(howName){
	this.name = howName;
}

Person.prototype.getName = function(){
	return this.name;
}

var person = new Person("MT");
console.log(person.getName());

  一個函數,若是建立的目的就是但願結合new前綴來調用,那它就被稱爲構造器函數。按照約定,它們保存在以大寫格式命名的變量裏。若是調用構造函數時沒有在前面加上new ,可能會發生很是糟糕的事情,(這時將會以函數的方式調用,因爲函數的方式調用this是全局對象,這時不會返回新對象,而是在全局對象上添加屬性。)既沒有編譯時警告,,也沒有運行時警告,因此大寫約定很是重要。

 

 apply/call調用模式

  由於JavaScript是一門函數式的面向對象編程語言,因此函數能夠擁有方法。

  apply/call方法容許咱們選擇this的值。apply方法接受兩個參數,第一個是要綁定的this的值,第二個參數是參數數組。call方法第一個參數是要綁定的this的值,後面緊跟的是相關的參數。

function setAge(age){
	this.age = age;
}

setAge.call(myObj, 23);	
console.log(myObj.age);		//23

setAge.apply(myObj, [24]);
console.log(myObj.age);		//24
相關文章
相關標籤/搜索