日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript中this的五种绑定方式详解

發布時間:2025/6/17 javascript 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript中this的五种绑定方式详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 this的五種綁定方式

1.1 默認綁定

默認綁定是指當函數調用時,沒有為其指定對象上下文,此時會將該函數的this綁定到全局對象(window對象)。自ES5有了嚴格模式之后,默認綁定方式又分為非嚴格模式的默認綁定和嚴格模式的默認綁定。

1.1.1 非嚴格模式

在非嚴格模式下,函數的默認綁定只能綁定到全局對象window,見下面例子:

var myName = 'syzdev' // 相當于 window.myName = 'syzdev' function sayName() {// 這里的 this === windowconsole.log(this === window); // trueconsole.log(this.myName); // syzdev } sayName()

在這個例子中,首先聲明了一個全局變量myName:

var聲明的變量為全局變量,并且會將該變量添加為全局對象window的屬性,需要注意的是,例子中的var不可修改為ES6中的let或const,不然結果大有不同,有興趣的讀者可以查閱資料“var、let、const的區別”。

再定義了一個sayName()函數,在函數中輸出this.myName,最后直接調用sayName()函數,再調用時,由于沒有指定其對象上下文,所以觸發了默認綁定,即將函數中的this綁定到全局對象window上,因此在函數內this === window,最后輸出的this.myName為 syzdev。

1.1.2 嚴格模式

關于嚴格模式,這里不做介紹,若不了解的讀者可以閱讀MDN-嚴格模式。

在嚴格模式下,有一項規定為“禁止this關鍵字指向全局對象window”,此時this會綁定到undefined,見下面例子:

// 開啟嚴格模式 'use strict' var myName = 'syzdev' function sayName() {// 這里的 this !== windowconsole.log(this === window); // falseconsole.log(this); // undefinedconsole.log(this.myName); // 報錯:Uncaught TypeError: Cannot read properties of undefined (reading 'myName') } sayName()

在這個例子中,在代碼頂部使用'use strict'聲明了嚴格模式,由于在嚴格模式下禁止this綁定到全局對象window,所以函數中的this !== window,輸出this為undefined,因此輸出this.myName時會直接拋出錯誤“Uncaught TypeError: Cannot read properties of undefined (reading ‘name’)”。

由于嚴格模式可以聲明為全局或個別函數內,上面的例子中就是聲明為全局嚴格模式,若聲明為函數內嚴格模式,偽代碼如下:

function sayName() {'use strict'... }

需要注意的是,嚴格模式并不會影響到調用函數內的默認綁定,見下面例子:

var myName = 'syzdev' function sayName() {// 這里的 this === windowconsole.log(this === window); // trueconsole.log(this.myName); // syzdev }function strictSayName() {// 函數內的嚴格模式'use strict'sayName() } strictSayName()

在這個例子中,定義函數strictSayName()并在函數內部聲明嚴格模式,再調用sayName()函數,此時sayName()函數內部依然能夠將this綁定到全局對象window上。

1.2 隱式綁定

隱式綁定是日常開發中最為常見的綁定方式,即調用函數時為函數指明其對象上下文,此時函數中的this就為對象本身,見下面例子:

var personObj = {myName: 'syzdev',sayName: function() {console.log(this === personObj) // trueconsole.log(this.myName); // syzdev} } personObj.sayName()

在這個例子中,定義一個personObj對象,包含myName屬性和sayName()方法,通過對象personObj.sayName()調用函數,此時就會觸發this隱式綁定,函數中的this就是personObj本身。

但隱式綁定還可能會出現綁定丟失的情況,此時隱式綁定就會變成了默認綁定,見下面例子:

var personObj = {myName: '123',sayName: function() {console.log(this === window); // trueconsole.log(this.myName); // undefined} } var anotherSayName = personObj.sayName anotherSayName()

在這個例子中,把personObj.sayName()函數賦值給了變量anotherSayName,再直接使用anotherSayName()調用,此時雖然調用的還是sayName()函數,但是卻丟失了對象上下文,此時隱式綁定變成了默認綁定,anotherSayName()函數內的this綁定到全局對象window上,由于window對象上沒有myName屬性,所以輸出undefined。

1.3 顯式綁定

顯示綁定顧名思義,通過調用call/apply/bind方法,強制將函數中的this綁定到指定的對象,三者區別如下:

  • call()接受的是多個對象作為參數。
  • apply()接受的是多個對象組成的數組作為參數。
  • bind()返回的是一個函數,除此之外使用方法與call()一樣。

使用call/apply/bind實現顯示綁定的方法如下:

  • 不含參數的使用方法:
  • function foo() {console.log(this.myName); }var myName = 'window myName' var personObj = {myName: 'personObj myName' }foo() // window myName foo.call(personObj) // personObj myName foo.apply(personObj) // personObj myName foo.bind(personObj)() // personObj myName

    在這個例子中,直接調用sayName()函數會觸發默認綁定,函數內的this綁定到全局對象window,所以輸出window myName。由于該例子中函數不需要傳參,所以在使用call/apply/bind方法時,不需要為其傳遞除this對象外的其他參數,其效果都是一致的,都是將sayNname()函數內的this綁定到personObj對象,最后輸出的myName為personObj對象中的personObj myName。

  • 含參數的使用方法:
  • function foo(name, age) {console.log(name, age) }foo('syzdev', 18) // 直接調用函數傳遞參數 foo.call(this, 'syzdev', 18) // call執行函數,第一個參數指定this對象,后續參數依次為函數的傳參 foo.apply(this, ['syzdev', 18]) // apply執行函數,第一個參數指定this對象,第二個參數為一個數組,數組中為函數的傳參 foo.bind(this, 'syzdev', 18)() // bind執行函數,返回的是一個函數,除此之外用法與call相同 // 輸出結果 // syzdev 18 // syzdev 18 // syzdev 18 // syzdev 18

    代碼詳解見注釋。

    1.4 new綁定

    在ES6以前,生成一個實例對象的方法是使用構造函數,構造函數只是一個普通的函數,當使用new操作符調用構造函數時,JavaScript解釋器便會在底層創建一個新對象,構造函數內的this綁定的就是這個新對象,見下面例子:

    function Person(name, age) {this.name = namethis.age = age } var person = new Person('syzdev', 18)

    在這個例子中,使用new操作符執行一個構造函數,創建一個person對象,在構造函數內會創建一個新的對象,將函數內的this綁定到這個新對象上,如果函數內部沒有返回其他對象,則構造函數會默認返回這個新對象,流程如下圖所示:

    1.5 箭頭函數綁定

    箭頭函數是ES6中的一個重要特性,在箭頭函數中沒有自己的this,其this是根據外層的作用域來決定的,箭頭函數內的this指的是定義時所在的對象,是在函數定義時已經決定了,而不是像普通函數一樣在調用時綁定this對象,見下面例子:

    var foo = () => {console.log(this.myName); }var myName = 'window myName' var personObj = {myName: 'personObj myName' }foo() // window myName foo.call(personObj) // window myName foo.apply(personObj) // window myName foo.bind(personObj)() // window myName

    在這個例子中,函數foo定義為箭頭函數,由于箭頭函數沒有自己的this,其this值在定義時已經決定,所以無法被call/apply/bind方法所改變,在該例子中其this值為全局對象window,所以四種方法調用foo()函數的結果都為window myName。

    2 this綁定的優先級

    所謂this綁定的優先級,指的是當函數執行時若同時指定了多個this對象時的綁定順序。

  • 隱式綁定 > 默認綁定
  • 在第2章的例子中已經證明了這個結論:

    var personObj = {myName: 'syzdev',sayName: function() {console.log(this === personObj) // trueconsole.log(this.myName); // syzdev} } // 相當于 window.personObj.sayName() personObj.sayName()

    在這個例子中,personObj.sayName()為隱式綁定,而personObj.sayName()相當于window.personObj.sayName()可見window對象的默認綁定失效了,最終執行的this依舊是personObj,所以隱式綁定 > 默認綁定。

  • 顯示綁定 > 隱式綁定
  • 修改第3章的例子如下:

    function foo() {console.log(this.myName); }var myName = 'window myName' var personObj = {myName: 'personObj myName',foo: foo // 修改部分 }personObj.foo.call(window) // window myName

    在上面例子中的personObj.foo為隱式綁定,再通過call將foo()函數中的this顯示綁定到全局對象window上,最終輸出的結果還是window myName,可見顯示綁定 > 隱式綁定。

  • new綁定 > 顯示綁定
  • function foo(name) {this.name = name }// 創建對象obj var obj = {} // 將obj綁定為函數foo中的this var bindFoo = foo.bind(obj) bindFoo('syzdev') console.log(obj.name) // syzdevvar bindObj = new bindFoo('bind syzdev') console.log(bindObj.name) // bind syzdev

    在這個例子中,使用bind方法將obj綁定到foo()函數中并返回一個新的函數bindFoo,在使用new操作符創建一個新的對象bindObj時,函數bindFoo()的this指向發生了改變,原本函數bindFoo()中的this指向的是obj,在使用new操作符后指向了一個新的對象并返回賦值給了bindObj。

    2.2 總結

    在討論this綁定優先級時之所以不討論箭頭函數,是因為箭頭函數的this在其函數定義時就已經確定,不存在優先級一說。其他四種綁定方式的優先級如下,由高到低:

  • new綁定
  • 顯示綁定
  • 隱式綁定
  • 默認綁定
  • 總結

    以上是生活随笔為你收集整理的JavaScript中this的五种绑定方式详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 手机在线视频一区 | 国产精品亲子伦对白 | 国内久久精品视频 | av电影在线观看网址 | 91精品在线观看入口 | 一女二男一黄一片 | 男ji大巴进入女人视频 | 国产无遮挡又黄又爽又色 | 热99在线 | 欧美10p | 麻豆视频免费网站 | 亚洲一二区 | 青青草免费在线观看视频 | 欧美顶级少妇做爰 | 国产精品羞羞答答在线观看 | 九九热最新 | 欧美大色一区 | 欧美成人免费在线视频 | 中文字幕一区二区三区人妻四季 | 又黄又爽又刺激的视频 | 极品美女被c | 精品久久一二三区 | 最新激情网 | 97福利影院 | 亚洲伊人网站 | 美日韩三级 | 日韩精品午夜 | 黄色工厂在线观看 | 高清国产一区二区三区四区五区 | 国产一区二区三区麻豆 | 欧美大黄视频 | 伊人免费视频二 | 欧美高清videos高潮hd | 欧美色亚洲 | 国产a免费| 97精品人妻一区二区三区香蕉 | jizz教师| 亚洲欧美国产毛片在线 | 91看视频 | 波多野结衣调教 | 亚洲国产经典 | 亚洲老女人视频 | 全部孕妇毛片 | 久久国语精品 | 国产字幕在线观看 | 久久精品久久精品久久精品 | 久久日韩精品 | 91.久久| 青娱乐自拍视频 | 瑟瑟视频免费观看 | 中文字幕五码 | 欧美亚洲视频一区 | 野花中文免费观看6 | 天天久久 | 日本www网站 | 中国大陆高清aⅴ毛片 | 非洲黄色片 | 午夜免费看片 | 国产三级伦理片 | 久久这里只有精品8 | 精品一区二区三区在线观看 | 大地资源高清播放在线观看 | 91日本精品 | 欧美一级爱爱视频 | 国产伦精品一区二区三区照片91 | 成人高潮片免费视频 | 男人天堂资源网 | 雪花飘电影在线观看免费高清 | 国产微拍精品一区 | 影音先锋91 | 四虎影院在线观看免费 | 国产9区| 国产视频一区二区在线 | 精品在线视频观看 | wwwxxxx国产 | 久久久精品国产免费爽爽爽 | 亚洲 欧美 日韩系列 | 日本在线第一页 | 在线视频 91 | 一本大道久久久久精品嫩草 | 久久久久亚洲av无码专区 | 自拍偷拍亚洲精品 | 国产欧美一区二区三区在线老狼 | 亚洲一区二区三区在线播放 | 欧美成人一区二免费视频软件 | 欧美高清在线一区 | 日本少妇18p| 浓精喷进老师黑色丝袜在线观看 | 日韩青青草| 日韩一区二区免费在线观看 | 国产欧美日本 | 超碰天天 | 国产乱码一区二区三区 | 久久人 | 九九热这里有精品视频 | 亚洲免费观看高清 | 国产影视一区二区 | 超碰天天操 | 亚洲狼人综合网 |