深刻javascript——無處不在的this

有人的地方就有江湖,有函數的地方就有this。而this在不一樣的環境下,又表現爲不一樣的形式,不免讓人有種此this非彼this的疑惑javascript

在java等面向對象的語言中,this指的就是當前對象,而在javascript中這就不靈了,javascript中this是在編譯期動態綁定的,這就造成了一把雙刃劍:足夠靈活卻又容易讓人迷惑。在javascript中this能夠是全局對象、當前對象甚至任意對象(obj.call(this))。
咱們經過函數的幾種不一樣調用方式來看一下各自this的意義:java

做爲對象方法調用

在javascript中函數也是個對象,所以,函數能夠做爲一個對象的屬性出現:程序員

var object = {
    name:"jeffie",
    sayWhat:function(){
        console.log(this.name + ":hello"); //jeffie:hello
    }
 }
object.sayWhat();

此處的this指向object對象,也就是函數所在的對象。segmentfault

做爲函數調用

當函數直接被調用時,此時函數中的this指向全局變量,也就是window對象:數組

function obj(){
    console.log(this);
 }
obj();//Window

構造函數中的this

在做爲構造函數調用時,this指向的是新生成的實例對象:閉包

function Plugin(name,type){
    this.name = name;
    this.type = type;
 }

 var plugin = new Plugin("core",1);
 console.log(plugin.name);//core

使用apply或者call調用

javascript中每一個函數都包含兩個方法:apply()和call(),這兩個方法很是強大,它們能夠切換函數的上下文執行環境,也就是說能夠修改this綁定的對象。簡單來講,這兩個方法能夠用來設置函數的this,兩個方法都接收兩個參數,第一個參數是運行函數的做用域,第二個參數是參數對象,惟一的區別是apply第二個參數爲參數數組(Array或者arguments):app

function Plugin(name,type){
    this.name = name;
    this.type = type;
    this.debugs = function(name,type){
        console.log(this); //Object {name: "base", type: 3} 
    }
 }

 var plugin1 = new Plugin("core",1);
 var plugin2 = {name:"base",type:3};
 console.log(plugin1.debugs.call(plugin2));

經過上面的示例能夠看出this值再也不指向Plugin對象了,而是指向了plugin2的對象。函數

閉包中使用this

一般咱們理解this對象是運行時基於函數綁定的,全局函數中this對象就是window對象,而當函數做爲對象中的一個方法調用時,this等於這個對象。因爲匿名函數的做用域是全局性的,所以閉包的this一般指向全局對象window:this

var scope = "global";
var object = {
    scope:"local",
    getScope:function(){
        return function(){
            return this.scope;
        }
    }
}

調用object.getScope()()返回值爲global而不是咱們預期的local,在閉包中函數做爲某個對象的方法調用時,要特別注意,該方法內部匿名函數的this指向的是全局變量。參考上一篇閉包
這屬於 JavaScript 的設計缺陷,正確的設計方式是內部函數的 this 應該綁定到其外層函數對應的對象上,爲了規避這一設計缺陷,聰明的 JavaScript 程序員想出了變量替代的方法,只須要把外部函數做用域的this存放到一個閉包能訪問的變量裏面便可,約定俗成,該變量通常被命名爲 that:debug

var scope = "global";
var object = {
    scope:"local",
    getScope:function(){
        var that = this;
        return function(){
            return that.scope;
        }
    }
}
object.getScope()()返回值爲local。
相關文章
相關標籤/搜索