我要投稿
  • 您當前的位置:中國教育資源網 -> 技術教程 -> 服務器網絡 -> 服務器教程 -> LinuxBSD教程 -> 教程內容
  • [ 收藏本頁教程 ]
  • 詳解 JavaScript 中的 this

    教程作者:本站    教程來源:本站整理   教程欄目:LinuxBSD教程    收藏本頁

    其實如果完全掌握了this的工作原理,自然就不會走進這些坑。來看下以下這些情況中的this分別會指向什么:

    1.全局代碼中的this

    1
    alert(x);// 全局變量x值為2

    全局范圍內的this將會指向全局對象,在瀏覽器中即使window。

    2.作為單純的函數調用

    1
    2
    3
    4
    5
    function fooCoder(x) {
    this.x = x;
    }
    fooCoder(2);
    alert(x);// 全局變量x值為2

    這里this指向了全局對象,即window。在嚴格模式中,則是undefined。

    3.作為對象的方法調用

    1
    2
    3
    4
    5
    6
    7
    8
    var name = "clever coder";
    var person = {
    name : "foocoder",
    hello : function(sth){
    console.log(this.name + " says " + sth);
    }
    }
    person.hello("hello world");

    輸出 foocoder says hello world。this指向person對象,即當前對象。

    4.作為構造函數

    1
    new FooCoder();
    函數內部的this指向新創建的對象。

    5.內部函數

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var name = "clever coder";
     
    var person = {
    name : "foocoder",
    hello : function(sth){
    var sayhello = function(sth) {
    console.log(this.name + " says " + sth);
    };
    sayhello(
    }
     
    person.hello("hello world");//clever coder says hello world

    在內部函數中,this沒有按預想的綁定到外層函數對象上,而是綁定到了全局對象。這里普遍被認為是JavaScript語言的設計錯誤,因為沒有人想讓內部函數中的this指向全局對象。一般的處理方式是將this作為變量保存下來,一般約定為that或者self:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var name = "clever coder";
    var person = {
    name : "foocoder",
    hello : function(sth){
    var that = this;
    var sayhello = function(sth) {
    console.log(that.name + " says " + sth);
    };
    sayhello(sth);
    }
    }
    person.hello("hello world");//foocoder says hello world

    6.使用call和apply設置this

    1
    person.hello.call(person, "world");
    apply和call類似,只是后面的參數是通過一個數組傳入,而不是分開傳入。兩者的方法定義:

    1
    2
    3
    call( thisArg [,arg1,arg2,… ] ); // 參數列表,arg1,arg2,...
     
    apply(thisArg [,argArray] );    // 參數數組,argArray

    兩者都是將某個函數綁定到某個具體對象上使用,自然此時的this會被顯式的設置為第一個參數。

    簡單地總結

    簡單地總結以上幾點,可以發現,其實只有第六點是讓人疑惑的。

    其實就可以總結為以下幾點:

    1. 當函數作為對象的方法調用時,this指向該對象。
    2. 當函數作為淡出函數調用時,this指向全局對象(嚴格模式時,為undefined)
    3. 構造函數中的this指向新創建的對象
    4. 嵌套函數中的this不會繼承上層函數的this,如果需要,可以用一個變量保存上層函數的this。

    再總結的簡單點,如果在函數中使用了this,只有在該函數直接被某對象調用時,該this才指向該對象。

    1
    2
    3
    obj.foocoder();
    foocoder.call(obj, ...);
    foocoder.apply(obj, …);

    更進一步

    我們可能經常會寫這樣的代碼:

    1
    $("#some-ele").click = obj.handler;
    如果在handler中用了this,this會綁定在obj上么?顯然不是,賦值以后,函數是在回調中執行的,this會綁定到$(“#some-div”)元素上。這就需要理解函數的執行環境。本文不打算長篇贅述函數的執行環境,可以參考《javascript高級程序設計》中對執行環境和作用域鏈的相關介紹。這里要指出的時,理解js函數的執行環境,會更好地理解this。

    那我們如何能解決回調函數綁定的問題?ES5中引入了一個新的方法,bind():

    1
    2
    3
    fun.bind(thisArg[, arg1[, arg2[, ...]]])
     
    thisArg

    當綁定函數被調用時,該參數會作為原函數運行時的this指向.當使用new 操作符調用綁定函數時,該參數無效.

    1
    arg1, arg2, ...
    當綁定函數被調用時,這些參數加上綁定函數本身的參數會按照順序作為原函數運行時的參數.

    該方法創建一個新函數,稱為綁定函數,綁定函數會以創建它時傳入bind方法的第一個參數作為this,傳入bind方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數.

    顯然bind方法可以很好地解決上述問題。

    1
    2
    $("#some-ele").click(person.hello.bind(person));
    //相應元素被點擊時,輸出foocoder says hello world

    其實該方法也很容易模擬,我們看下Prototype.js中bind方法的源碼:

    1
    2
    3
    4
    5
    6
    7
    Function.prototype.bind = function(){
      var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
      return function(){
        return fn.apply(object,
          args.concat(Array.prototype.slice.call(arguments)));
      };
    };

    明白了么?

    我要投稿   -   廣告合作   -   關于本站   -   友情連接   -   網站地圖   -   聯系我們   -   版權聲明   -   設為首頁   -   加入收藏   -   網站留言
    Copyright © 2009 - 20012 www.mmogirl.net All Rights Reserved.中國教育資源網 版權所有  
     
    潘甜甜七夕果冻传媒在线_月夜影视在线观看免费完整_国产成人18黄网站视频_亚洲无?码国产精品