我要投稿
  • 您當前的位置:中國教育資源網 -> 技術教程 -> 服務器網絡 -> 服務器教程 -> 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.obscurenation.com All Rights Reserved.中國教育資源網 版權所有  
     
    彩16app 茶陵县 | 车致 | 肇州县 | 武川县 | 铁力市 | 马鞍山市 | 江北区 | 银川市 | 会宁县 | 合山市 | 秦安县 | 息烽县 | 南川市 | 资兴市 | 晋城 | 汉寿县 | 依安县 | 罗城 | 礼泉县 | 文登市 | 都匀市 | 涿鹿县 | 儋州市 | 山阴县 | 河间市 | 沙洋县 | 柳江县 | 称多县 | 巴塘县 | 维西 | 弋阳县 | 宜黄县 | 南澳县 | 郯城县 | 马公市 | 新兴县 | 涿鹿县 | 永城市 | 星座 | 平顶山市 | 闸北区 | 平南县 | 息烽县 | 芷江 | 竹山县 | 高州市 | 汉阴县 | 万州区 | 南充市 | 新兴县 | 嘉荫县 | 巴青县 | 连城县 | 芦溪县 | 兰州市 | 上高县 | 玉门市 | 大庆市 | 通许县 | 巴南区 | 金塔县 | 寿阳县 | 中阳县 | 晋州市 | 慈利县 | 濮阳县 | 绩溪县 | 吴桥县 | 且末县 | 马关县 | 鄄城县 | 台中县 | 石首市 | 通道 | 松桃 | 台湾省 | 闽清县 | 化州市 | 德钦县 | 陇西县 | 崇礼县 | 开原市 | 洪湖市 | 黑河市 | 屯留县 | 文成县 | 常州市 | 乌鲁木齐县 | 木里 | 奈曼旗 | 乐东 | 晋城 | 鄂伦春自治旗 | 高阳县 | 马公市 | 句容市 | 吉隆县 | 普兰店市 | 阿城市 | 江津市 | 义马市 | 锦屏县 | 富蕴县 | 玛曲县 | 陇川县 | 赫章县 | 利川市 | 如皋市 | 石河子市 | 沁阳市 | 张家口市 | 六盘水市 | 五台县 | 河池市 | 皮山县 | 彭泽县 | 射洪县 | 顺平县 | 乾安县 | 满洲里市 | 苏尼特左旗 | 孟州市 | 老河口市 | 如皋市 | 彩票 | 唐河县 | 营口市 | 佛坪县 | 龙南县 | 静宁县 | 武宁县 | 丰台区 | 濉溪县 | 娱乐 | 曲沃县 | 珠海市 | 凤庆县 | 徐汇区 | 阿城市 | 漳州市 | 凭祥市 | 大悟县 | 万载县 | 开原市 | 镇原县 | 凤山县 | 富裕县 | 当雄县 | 赣榆县 | 革吉县 | 固镇县 | 白山市 | 宜章县 | 石泉县 | 汉沽区 | 康平县 | 锡林浩特市 | 新兴县 | 炉霍县 | 红河县 | 怀集县 | 青岛市 | 鄂伦春自治旗 | 盘锦市 | 台南县 | 翁源县 | 宝应县 | 区。 | 清苑县 | 勐海县 | 翁牛特旗 | 清丰县 | 聂荣县 | 巴林左旗 | 渑池县 | 保山市 | 轮台县 | 马公市 | 临夏市 | 巴塘县 | 桂林市 | 通城县 | 海盐县 | 新竹县 | 宜春市 | 卓尼县 | 宣城市 | 民丰县 | 辉南县 | 武冈市 | 托克逊县 | 漠河县 | 宜丰县 | 衡东县 | 达孜县 | 彭水 | 织金县 | 白朗县 | 韩城市 | 巧家县 | 濮阳县 | 姜堰市 | 寻甸 | 漳浦县 | 元朗区 | 永州市 | 吉林省 | 米易县 | 阿坝 | 襄汾县 | 惠来县 | 读书 | 定陶县 | 德格县 | 于田县 | 嘉义市 | 洛川县 | 志丹县 | 万山特区 | 易门县 | 丹棱县 | 微山县 | 奉贤区 | 甘孜 | 政和县 | 昌吉市 | 舞阳县 | 托里县 | 扬中市 | 高州市 | 成安县 | 寻乌县 | 蓝山县 | 龙州县 | 印江 | 红桥区 | 满洲里市 | 柳河县 | 苍南县 | 伊春市 | 融水 | 九寨沟县 | 贺州市 | 昌邑市 | 偏关县 | 射洪县 | 平阳县 | 绥阳县 | 鄯善县 | 扎赉特旗 | 郓城县 |