JS基礎:this的指向以及call、apply的做用

this 的指向數組

  在具體的實際應用中,this 的指向沒法在函數定義時肯定,而是在函數執行的時候才肯定的,根據執行時的環境大體能夠分爲如下3種:瀏覽器

一、當函數做爲普通函數調用時,this 指向全局對象app

二、當函數做爲對象的方法調用時,this 指向該對象函數

三、當函數做爲構造器調用時,this 指向新建立的對象this

示例一:spa

window.name = 'myname';
function getName() {
    console.log(this.name);
}
getName(); //輸出myname

示例二:prototype

var boy = {
    name: 'Bob',
    getName: function() {
        console.log(this.name);
    }
}
boy.getName(); //輸出Bob

示例三:code

function Boy(name) {
    this.name = name;
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //輸出Bob

對於示例三,還有一種特殊狀況,就是當構造函數經過 "return" 返回的是一個對象的時候,這次運算的最終結果返回的就是這個對象,而不是新建立的對象,所以 this 在這種狀況下並無什麼用。對象

示例四:blog

function Boy(name) {
    this.name = name;
    return { //返回一個對象
        name: 'Jack'
    }
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //輸出Jack

示例五:

function Boy(name) {
    this.name = name;
    return 1; //返回非對象
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //輸出Bob

call 和 apply 的做用

  apply 接受兩個參數,第一個參數指定了函數體內 this 的指向,第二個參數是一個數組或類數組,用於傳遞被調用函數的參數列表。

示例一:

function getInfo() {
    console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}
var boy1 = {
    name: 'Bob',
    age: 12
}
getInfo.apply(boy1,['sing','swimming']); //輸出Bob like sing and swimming

  call 傳入參數的數量是不固定的,跟 apply 相同的是,第一個參數也是用於指定函數體內 this 的指向,從第二個參數開始日後,每一個參數被依次傳入被調用函數。

示例二:

function getInfo() {
    console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}
var boy1 = {
    name: 'Bob',
    age: 12
}
getInfo.call(boy1,'sing','shopping'); //輸出Bob like sing and shopping

  此外,大部分高級瀏覽器還實現了 bind 方法,bind 方法會返回一個新函數,稱爲綁定函數,當調用這個綁定函數時,綁定函數會以建立它時傳入的第一個參數做爲 this,傳入的第二個以及之後的參數加上綁定函數運行時自己的參數按照順序做爲原函數的參數來調用原函數。

示例三:

var boy1 = {
  name: 'Bob',
  age: 12
}
var getInfo = function() {
  console.log(this.name + ' like ' + arguments[0] + ' and ' + arguments[1]);
}.bind(boy1,'sing');
getInfo('shopping');  //輸出Bob like sing and shopping

示例四:模擬瀏覽器的 bind 方法

Function.prototype.bind = function(obj){
    var self = this;
    return function(){
        return self.apply(obj,arguments);
    }
};
var boy1 = {
    name: 'Bob',
    age: 12
};
var func = function(){
    console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}.bind(boy1);
func('sing','shopping');

丟失的 this

  在某些狀況下會丟失 this 的指向,此時,咱們就須要藉助 call、apply 和 bind 來改變 this 的指向問題。

示例一:當 "getName" 方法做爲 "boy" 對象的屬性調用時,this 指向 "boy" 對象,當另一個變量引用 "getName" 方法時,由於它是做爲普通函數調用,因此 this 指向全局對象window

var boy = {
    name: 'Bob',
    getName: function() {
        console.log(this.name);
    }
}
boy.getName(); //輸出Bob
var getBoyName = boy.getName;
getBoyName(); //輸出undefind

示例二:即便在函數內部定義的函數,若是它做爲普通對象調用,this 一樣指向 window 對象

var boy1 = {
    name: 'Bob',
    age: 12,
    getInfo: function() {
        console.log(this.name);
        function getAge() {
            console.log(this.age);
        }
        getAge();
    }
}
boy1.getInfo(); //Bob
                //undefind
相關文章
相關標籤/搜索