最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中的this關鍵字用法詳解

 更新時間:2023年05月11日 10:24:25   作者:白哥學前端  
在編寫JavaScript應用的時候,我們經(jīng)常會使用this關鍵字。那么this關鍵字究竟是怎樣工作的,它的設計有哪些好的地方,有哪些不好的地方,本文帶大家全面系統(tǒng)地認識這個老朋友,感興趣的小伙伴可以借鑒閱讀

先舉一個生活例子:

小明正在跑步,他看起來很開心

這里的小明是主語,如果沒有這個主語,那么后面的代詞『他』將毫無意義。有了主語,代詞才有了可以指代的事物。

類比到JavaScript的世界中,我們在調用一個對象的方法的時候,需要先指明這個對象,再指明要調用的方法。

var xiaoming = {
  name: 'Xiao Ming',
  run: function() {
    console.log(`${this.name} seems happy`);
  },
};

xiaoming.run();

在上面的例子中,第8行中的xiaoming指定了run方法運行時的主語。因此,在run中,我們才可以用this來代替xiaoming這個對象。可以看到this起了代詞的作用。

同樣的,對于一個JavaScript類,在將它初始化之后,我們也可以用類似的方法來理解:類的實例在調用其方法的時候,將作為主語,其方法中的this就自然變成了指代主語的代詞。

class People {
  constructor(name) {
    // 在用new關鍵字實例化一個對象的時候,相當于在說,
    // “創(chuàng)建一個People類實例(主語),它(this)的name是……”
    // 所以這里的this就是新創(chuàng)建的People類實例
    this.name = name;
  }
  
  run() {
    console.log(`${this.name} seems happy.`)  
  }
}

// new關鍵字實例化一個類
var xiaoming = new People('xiaoming');
xiaoming.run();

這就是我認為this關鍵字設計得精彩的地方!如果將調用方法的語句var xiaoming = new People('xiaoming');和方法本身的代碼連起來,像英語一樣讀,其實是完全通順的。

this的綁定

句子的主語是可以變的,例如在下面的場景中,run被賦值到小芳(xiaofang)身上之后,調用xiaofang.run,主語就變成了小芳!

var xiaofang = {
  name: 'Xiao Fang',
};

var xiaoming = {
  name: 'Xiao Ming',
  run: function() {
    console.log(`${this.name} seems happy`);
  },
};

xiaofang.run = xiaoming.run;
// 主語變成了小芳
xiaofang.run();

但是如果小明很摳門,不愿意將run方法借給小芳以后,this就變成了小芳的話,那么小明要怎么做呢?他可以通過Function.prototype.bind讓run運行時候的this永遠為小明自己。

var xiaofang = {
  name: 'Xiao Fang',
};

var xiaoming = {
  name: 'Xiao Ming',
  run: function() {
    console.log(`${this.name} seems happy`);
  },
};

// 將小明的run方法綁定(bind)后,返回的還是一個
// 函數(shù),但是這個函數(shù)之后被調用的時候就算主語不是小明,
// 它的this依然是小明
xiaoming.run = xiaoming.run.bind(xiaoming);

xiaofang.run = xiaoming.run;
// 主語雖然是小芳,但是最后this還是小明
xiaofang.run();

那么同一個函數(shù)被多次bind之后,到底this是哪一次bind的對象呢?你可以自己嘗試看看。

call與apply

Function.prototype.call允許你在調用一個函數(shù)的時候指定它的this的值。

var xiaoming = {
    name: 'Xiao Ming'
};

function run(today, mood) {
    console.log(`Today is ${today}, ${this.name} seems ${mood}`);
}

// 函數(shù)的call方法第一個參數(shù)是this的值
// 后續(xù)只需按函數(shù)參數(shù)的順序傳參即可
run.call(xiaoming, 'Monday', 'happy')

Function.prototype.applyFunction.prototype.call的功能是一模一樣的,區(qū)別進在于,apply里將函數(shù)調用所需的所有參數(shù)放到一個數(shù)組當中。

var xiaoming = {
    name: 'Xiao Ming'
};

function run(today, mood) {
    console.log(`Today is ${today}, ${this.name} seems ${mood}`);
}

// apply只接受兩個參數(shù)
// 第二個參數(shù)是一個數(shù)組,這個數(shù)組的元素被按順序
// 作為run調用的參數(shù)
run.apply(xiaoming, ['Monday', 'happy'])

那么call/apply和上面的bind混用的時候是什么樣的行為呢?這個也留給大家自行驗證。但是在一般情況下,我們應該避免混用它們,否則會造成代碼檢查或者調試的時候難以跟蹤this的值的問題。

當方法失去主語的時候,this不再有?

其實大家可以發(fā)現(xiàn)我的用詞,當一個function被調用的時候是有主語的時候,它是一個方法;當一個function被調用的時候是沒有主語的時候,它是一個函數(shù)。當一個函數(shù)運行的時候,它雖然沒有主語,但是它的this的值會是全局對象。在瀏覽器里,那就是window。當然了,前提是函數(shù)沒有被bind過,也不是被applycall所調用。

那么function作為函數(shù)的情景有哪些呢?

首先,全局函數(shù)的調用就是最簡單的一種。

function bar() {
  console.log(this === window); // 輸出:true
}
bar();

立即調用的函數(shù)表達式(IIFE,Immediately-Invoked Function Expression)也是沒有主語的,所以它被調用的時候this也是全局對象。

(function() {
  console.log(this === window); // 輸出:true
})();

但是,當函數(shù)被執(zhí)行在嚴格模式(strict-mode)下的時候,函數(shù)的調用時的this就是undefined了。這是很值得注意的一點。

function bar() {
  'use strict';
  console.log('Case 2 ' + String(this === undefined)); // 輸出:undefined
}
bar();

不可見的調用

有時候,你沒有辦法看到你定義的函數(shù)是怎么被調用的。因此,你就沒有辦法知道它的主語。下面是一個用jQuery添加事件監(jiān)聽器的例子。

window.val = 'window val';

var obj = {
  val: 'obj val',
  foo: function() {
    $('#text').bind('click', function() {
      console.log(this.val);
    });
  }
};

obj.foo();

在事件的回調函數(shù)(第6行開始定義的匿名函數(shù))里面,this的值既不是window,又不是obj,而是頁面上idtext的HTML元素。

var obj = {
  foo: function() {
    $('#text').bind('click', function() {
      console.log(this === document.getElementById('text')); // 輸出:true
    });
  }
};

obj.foo();

這是因為匿名函數(shù)是被jQuery內部調用的,我們不知道它調用的時候的主語是什么,或者是否被bind等函數(shù)修改過this的值。所以,當你將匿名函數(shù)交給程序的其他部分調用的時候,需要格外地謹慎。

如果我們想要在上面的回調函數(shù)里面使用obj的val值,除了直接寫obj.val之外,還可以在foo方法中用一個新的變量that來保存foo運行時this的值。這樣說有些繞口,我們看下例子便知。

window.val = 'window val';

var obj = {
  val: 'obj val',
  foo: function() {
    var that = this; // 保存this的引用到that,這里的this實際上就是obj
    $('#text').bind('click', function() {
      console.log(that.val); // 輸出:obj val
    });
  }
};

obj.foo();

另外一種方法就是為該匿名函數(shù)bind了。

window.val = 'window val';

var obj = {
  val: 'obj val',
  foo: function() {
    $('#text').bind('click', function() {
      console.log(this.val); // 輸出:obj val
    }.bind(this));
  }
};

obj.foo();

總結

在JavaScript中this的用法的確是千奇百怪,但是如果利用自然語言的方式來理解,一切就順理成章了。不知道你讀完這篇文章的時候理解了嗎?

以上就是JavaScript中的this關鍵字用法詳解的詳細內容,更多關于JavaScript this關鍵字的資料請關注腳本之家其它相關文章!

相關文章

  • javascript DOM編程實例(智播客學習)

    javascript DOM編程實例(智播客學習)

    最近一直在努力學習DOM編程這塊,這是目前成就感最強烈的一塊了,畢老師很認真的給我們講解了相關知識,并在網(wǎng)上找了很多做的非常棒的網(wǎng)頁作為例程給我們進行講解
    2009-11-11
  • Selenium執(zhí)行JavaScript腳本的方法示例

    Selenium執(zhí)行JavaScript腳本的方法示例

    這篇文章主要介紹了Selenium執(zhí)行JavaScript腳本的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • echarts浮動顯示單位的實現(xiàn)方法示例

    echarts浮動顯示單位的實現(xiàn)方法示例

    這篇文章主要給大家介紹了關于echarts浮動顯示單位的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 微信小程序實現(xiàn)下載進度條的方法

    微信小程序實現(xiàn)下載進度條的方法

    本篇文章主要介紹了微信小程序實現(xiàn)下載進度條的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • 深入理解JavaScript 參數(shù)按值傳遞

    深入理解JavaScript 參數(shù)按值傳遞

    本篇文章主要介紹了深入理解JavaScript 參數(shù)按值傳遞,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 一文帶你理解微信小程序中RPC通信的實現(xiàn)

    一文帶你理解微信小程序中RPC通信的實現(xiàn)

    在微信小程序開發(fā)中,要實現(xiàn)兩個線程之間的通信是一項重要的任務,所以本文就來講講如何使用小程序的?postMessage?和?addListener?API?來實現(xiàn)在兩個線程之間進行高效的?RPC?通信吧
    2023-06-06
  • elementui?日歷組件el-calendar使用總結

    elementui?日歷組件el-calendar使用總結

    這篇文章主要介紹了elementui?日歷組件el-calendar使用總結,引用dayjs處理日期,結合el-calendar完美實現(xiàn),需要的朋友可以參考下
    2024-07-07
  • JSONP跨域請求實例詳解

    JSONP跨域請求實例詳解

    JSONP(JSON with Padding)是JSON的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。接下來通過本文給大家介紹JSONP跨域請求實例詳解,感興趣的朋友一起看下吧
    2016-07-07
  • javascript inneHTML的地雷

    javascript inneHTML的地雷

    大家都喜歡用innerHTML添加內容,但是innerHTML這東西在兩大陣營中有許多不同。
    2010-02-02
  • javascript閉包的使用之按鈕切換功能

    javascript閉包的使用之按鈕切換功能

    閉包就是能夠讀取其他函數(shù)內部變量的函數(shù).這篇文章通過實例代碼給大家介紹了javascript閉包的使用之按鈕切換功能,感興趣的朋友一起看看吧
    2018-08-08

最新評論

云龙县| 台东市| 福建省| 长岭县| 宾阳县| 通化市| 永兴县| 苍山县| 大洼县| 绥芬河市| 鹤山市| 池州市| 葵青区| 江山市| 通许县| 平乡县| 扶沟县| 鹿泉市| 长春市| 奉新县| 敦煌市| 通化县| 如东县| 益阳市| 安阳县| 安徽省| 松溪县| 搜索| 杭锦后旗| 武宣县| 宝应县| 上思县| 鄂托克前旗| 建平县| 花莲市| 宝鸡市| 蒙山县| 平武县| 德惠市| 昌平区| 宁晋县|