JavaScript的this老是指向一個對象,而這個對象是基於函數運行時動態綁定的,並不是函數聲明時綁定。數組
全部函數調用都會傳遞兩個隱式參數:arguments和this。
所謂隱式,也就意味着這些參數不會顯示列在函數簽名裏,可是它們默默地傳遞給函數並存在於函數做用域內。在函數內部,它們能夠像其餘顯式命名的參數同樣使用。app
arguments參數是傳遞給函數的全部參數的一個集合。該集合有一個length屬性,其值是所有參數的個數,單個參數值能夠像訪問數組索引同樣進行獲取。
但要避免將arguments參數做爲數組進行調用。能夠利用Array.prototype.slice.call(arguments, 0)將arguments參數轉換爲數組;函數
this參數引用了與該函數調用進行隱式關聯的一個對象,被稱之爲函數上下文。this
當函數做爲對象的方法被調用時,this指向該對象。該對象就成了函數上下文。prototype
window.name = 'global'; var obj = { name: 'staven', getName: function () { return this.name; } }; //做爲對象方法調用 console.log(obj.getName()); //staven
一種方式調用,函數的上下文時全局上下文——window對象。指針
window.name = 'global'; var obj = { name: 'staven', getName: function () { return this.name; } }; //做爲對象方法調用 console.log(obj.getName()); //staven //將函數引用指針賦給getName變量 var getName = obj.getName; //做爲普通函數調用 console.log(getName()); //global
常見的一種情形是,函數中的某個函數內部的this指向的是全局對象。解決這種問題,可var that = this;內部函數使用that代替this。code
將函數做爲構造器進行調用,咱們要在函數調用前使用new關鍵字。其上下文是新建立的對象實例。
構造器調用時,以下特殊行爲會發生:對象
構造器的目的是要建立一個新對象並對其進行設置,而後將其做爲構造器的返回值進行返回,是經過函數調用初始化建立新對象。索引
var Person = function () { this.name = "staven"; }; var obj = new Person(); console.log(obj.name); //staven
若是構造器顯式返回了一個對象,那麼這次運算最終返回這個對象,而不是this。ip
var Person = function () { this.name = "staven"; return { name: 'backedName' } }; var obj = new Person(); console.log(obj.name); //backedName
若是構造器不顯式返回任何數據,或返回的非對象數據,就不會存在上述問題。
var Person = function () { this.name = "staven"; return 'backedName'; }; var obj = new Person(); console.log(obj.name); //staven
經過call或apply調用函數,被調用的函數的this指向第一個參數指向的this。上下文可設爲任意值。每一個函數都有apply()和call()方法,使用其中一個方法,均可以顯示指定任何一個對象做爲其函數上下文。
經過函數的apply()方法來調用函數,咱們要給apply()傳入兩個參數:一個是做爲函數上下文的對象,另一個是做爲函數參數所組成的數組。call()方法的使用方式相似,惟一不一樣的是,給函數傳入的參數是一個參數列表,而不是單個數組。
當使用 call 或者 apply 的時候,若是咱們傳入的第一個參數爲null,函數體內的 this 會指向默認的宿主對象。
var obj1 = { name: 'jsor', getName: function () { return this.name; } }; var obj2 = { name: 'staven' }; console.log(obj1.getName()); //jsor console.log(obj1.getName.call(obj2)); //staven