深究JavaScript——函數調用與this詳解

this

  JavaScript的this老是指向一個對象,而這個對象是基於函數運行時動態綁定的,並不是函數聲明時綁定。數組

函數調用方式

  1. 做爲對象的方法調用
  2. 做爲普通函數進行調用
  3. 做爲構造器進行調用
  4. 經過apply()或call()方法進行調用

函數參數

  全部函數調用都會傳遞兩個隱式參數:arguments和this。
  所謂隱式,也就意味着這些參數不會顯示列在函數簽名裏,可是它們默默地傳遞給函數並存在於函數做用域內。在函數內部,它們能夠像其餘顯式命名的參數同樣使用。app

arguments參數

  arguments參數是傳遞給函數的全部參數的一個集合。該集合有一個length屬性,其值是所有參數的個數,單個參數值能夠像訪問數組索引同樣進行獲取。
  但要避免將arguments參數做爲數組進行調用。能夠利用Array.prototype.slice.call(arguments, 0)將arguments參數轉換爲數組;函數

this參數

  this參數引用了與該函數調用進行隱式關聯的一個對象,被稱之爲函數上下文。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關鍵字。其上下文是新建立的對象實例。
  構造器調用時,以下特殊行爲會發生:對象

  • 建立一個新的空對象
  • 傳遞給構造器的對象是this參數,從而成爲構造器的函數上下文。
  • 若是沒有顯式的返回值,新建立的對象則做爲構造器的返回值進行返回。

  構造器的目的是要建立一個新對象並對其進行設置,而後將其做爲構造器的返回值進行返回,是經過函數調用初始化建立新對象。索引

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

apply()或call()方法進行調用

  經過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
相關文章
相關標籤/搜索