<thead id="kdfuf"><font id="kdfuf"></font></thead>
<samp id="kdfuf"></samp>
    <nav id="kdfuf"><strong id="kdfuf"></strong></nav>
      中文字幕无码一区二区三区在线,久久精品人人做人人爽,国产一级内射无挡观看,十八禁在线黄色网站,日韩欧美国产另类久久久精品 ,少妇人妻偷人精品一区二区,久久午夜视频,亚洲春色AⅤ无码专区

      this解析 記錄分享

      2021-4-22    前端達(dá)人

      this指向的問(wèn)題也是JavaScript中的難點(diǎn)之一了,也是面試常問(wèn)的問(wèn)題,很多時(shí)候?qū)his指向的問(wèn)題就很懵逼,明明應(yīng)該是指向他,為什么又指向他了…所以我就學(xué)習(xí)了一下這方面的知識(shí),整理了一下,希望能夠幫助大家

      為什么要用this?

      首先看一段代碼

      function identify(){
          return this.name.toUpperCase()
      }
      function speak(){
          var greeting = '你好,我是'+identify.call(this)
          console.log(greeting)
      }
      
      var me ={
          name:'kyle'
      }
      
      var you ={
          name:"reader"
      }
      identify.call(me) 
      identify.call(you) 
      
      speak.call(me) //?  你好,我是KYLE
      speak.call(you) //? 你好,我是READER 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

      上面的這段代碼中可以從不同的上下文對(duì)象 me 和 you 中重復(fù)的使用identify函數(shù)和speak函數(shù)
      如果你不使用this的話 你就要顯式的將上下文對(duì)象作為參數(shù)傳遞進(jìn)去,比如這樣:

      function identify(context){
          return context.name.toUpperCase()
      }
      function speak(context){
          var greeting = '你好,我是'+identify(context)
          console.log(greeting)
      }
      
      var me ={
          name:'kyle'
      }
      
      var you ={
          name:"reader"
      }
      identify(me)
      identify(you) 
      
      speak(me) 
      speak(you) 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

      就像這樣,這樣看起來(lái)就不想上面那樣簡(jiǎn)潔了,你要把一個(gè)對(duì)象傳來(lái)傳去的

      認(rèn)識(shí)this

      剛見(jiàn)到this的時(shí)候 覺(jué)得this指向是這個(gè)函數(shù)自身,或者是函數(shù)的作用域,后來(lái)發(fā)現(xiàn)其實(shí)不是這樣的的,不過(guò)也不能說(shuō)錯(cuò)了,因?yàn)橛行┣闆r確實(shí)是這樣的,比如這樣:

      function foo(num){
          console.log('foo'+ num)
          this.count ++ 
      }
      foo.count = 0
      
      var i;
      for(i = 0;i<10;i++){
          if(i>5){
              foo.call(foo,i)
          }
      }
      console.log(foo.count) //4 這樣的話 this指向了foo本身  foo上面的count屬性++ 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      無(wú)法指向函數(shù)作用域

      var a = 3
      function foo() {
          var a = 2;
          bar.call(foo);
      }
      function bar() {
          console.log( this.a );
      }
      foo(); // undefined 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      我們要記住非常重要的一點(diǎn):this是在運(yùn)行的時(shí)候進(jìn)行綁定的,而不是在定義的時(shí)候綁定,this的綁定跟函數(shù)聲明的位置沒(méi)有關(guān)系,主要是取決于函數(shù)的調(diào)用方式,想要找到this指向誰(shuí),我們就要看懂函數(shù)是怎么調(diào)用的。

      綁定規(guī)則

      1.默認(rèn)綁定

      當(dāng)一個(gè)獨(dú)立函數(shù)正常調(diào)用的時(shí)候,不帶任何修飾的調(diào)用

      // 非嚴(yán)格模式下
      var a = 3
      function foo(){
          console.log(this.a) //a
      }
      foo() 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      這種情況下 this.a被解析成了了 全局變量a,this指向是全局對(duì)象

      // 嚴(yán)格模式下
      var a = 3
      function foo(){
          "use strict" 
          console.log(this.a) //TypeError
      }
      foo() 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      嚴(yán)格模式下 this不會(huì)指向全局對(duì)象 this綁定的是undefined

      2.隱式綁定

      調(diào)用位置上是否有上下文對(duì)象

      function foo(){
          console.log(this.a)
      }
      var obj = {
          a:2,
          foo:foo
      }
      obj.foo() //2 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      調(diào)用位置會(huì)使用obj上下文對(duì)象來(lái)引用函數(shù),foo被調(diào)用的時(shí)候 他的落腳點(diǎn)指向是obj對(duì)象,隱式綁定的規(guī)則就會(huì)把this指向這個(gè)上下文對(duì)象。所以this.a就跟 obj.a是一樣的

      function foo(){
          console.log(this.a)
      }
      var obj = {
          a:2,
          foo:foo
      }
      var obj2 = {
          a:3,
          obj:obj
      }
      obj2.obj.foo() //2 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      當(dāng)多層調(diào)用的時(shí)候 只有最后一層才會(huì)影響函數(shù)的調(diào)用位置 比如上面這個(gè) this綁定的還是 obj 而不是obj2

      注意

      隱式綁定會(huì)出現(xiàn)隱式丟失的問(wèn)題,會(huì)失去綁定對(duì)象,最后應(yīng)用默認(rèn)綁定

      var a = 3;
      function foo(){
          console.log(this.a);
      }
      var obj = {
          a:2,
          foo:foo
      }
      var bar = obj.foo
      bar() //3 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      bar 是 obj.foo的一個(gè)引用 他引用的是foo函數(shù)本身,此時(shí)bar就是一個(gè)不帶任何修飾的函數(shù)調(diào)用 應(yīng)用默認(rèn)綁定

      var a = 3;
      function foo(){
          console.log(this.a);
      }
      var obj = {
          a:2,
          foo:foo
      }
      setTimeout( obj.foo, 100 ) //3
      setTimeout(function(fn){
          fn()
      },100,obj.foo) //3 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      參數(shù)傳遞也是一種隱式賦值,回調(diào)函數(shù)丟失this是非常常見(jiàn)的…

      3.顯式綁定

      隱式綁定的時(shí)候我們必須在一個(gè)對(duì)象內(nèi)部包含一個(gè)指向函數(shù)的屬性,然后通過(guò)屬性間接引用函數(shù),把這個(gè)this間接隱式的綁定到這個(gè)對(duì)象上
      如果我們不想在對(duì)象內(nèi)部包含函數(shù)的引用 ,而想在某個(gè)對(duì)象上強(qiáng)制調(diào)用函數(shù)
      我們可以把這個(gè)函數(shù)綁定到對(duì)象的原型上,也算是不用再對(duì)象內(nèi)部包含函數(shù)了吧…
      更好的辦法是我們可以使用函數(shù)的 call() apply() bind() 這種方法

      function foo(){
          console.log(this.a)
      }
      
      var obj = {
          a:2
      }
      foo.call(obj) //2
      foo.apply(obj) //2 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      如果你第一個(gè)參數(shù)傳入的是一個(gè)原始類型 比如字符串 布爾 數(shù)字作為綁定對(duì)象 這些原始類型會(huì)被轉(zhuǎn)換為 對(duì)象的形式 new String() new Number()…

      硬綁定

      Function.prototype.bind()
      function foo(){
          console.log(this.a)
      }
      
      var obj = {
          a:2
      }
      var obj2 = {
          a:3
      }
      var bar = foo.bind(obj)  //會(huì)返回一個(gè)硬編碼的新函數(shù) 他會(huì)把參數(shù)設(shè)置為this的上下文
      bar.call(obj2) //2  返回的新函數(shù) 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      有些api 方法 會(huì)提供一個(gè)可選參數(shù) context 其作用跟bind一樣 確保你的回調(diào)函數(shù)使用指定的this 比如 array.forEach(fn,context)…

      4.new綁定

      使用new 來(lái)調(diào)用函數(shù)的時(shí)候會(huì)執(zhí)行以下操作
      1.創(chuàng)建一個(gè)全新的對(duì)象
      2.這個(gè)新對(duì)象會(huì)被執(zhí)行原型的鏈接
      3.新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this
      4.如果沒(méi)有返回其他的對(duì)象,那么函數(shù)會(huì)自動(dòng)返回這個(gè)對(duì)象

      function Foo(a){
          this.a = a
      }
      var bar = new Foo(2)
      console.log(bar.a) //2 
      
      • 1
      • 2
      • 3
      • 4
      • 5

      使用new 來(lái)調(diào)用Foo函數(shù) 會(huì)構(gòu)造一個(gè)新對(duì)象并把它綁定到Foo調(diào)用中的this上 然后返回了

      優(yōu)先級(jí)

      函數(shù)不帶任何修飾的時(shí)候單獨(dú)調(diào)用才會(huì)觸發(fā)默認(rèn)綁定 所以說(shuō)默認(rèn)綁定是優(yōu)先級(jí)最低的了

      那剩下三個(gè)規(guī)則哪個(gè)的優(yōu)先級(jí)最高?

      顯示綁定跟隱式綁定比較

      function foo(){
          console.log(this.a)
      }
      var obj1 = {
          a:1,
          foo:foo
      }
      
      var obj2 = {
          a:2,
          foo:foo
      }
      obj1.foo() //1
      obj2.foo() //2
      
      obj1.foo.call(obj2) //2
      obj2.foo.call(obj1) //1 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      可以看到 顯示綁定的優(yōu)先級(jí)還是更高一點(diǎn)

      new 綁定跟隱式綁定比較

      function foo(arg){
          this.a = arg
      }
      
      var obj1 ={
          foo:foo
      }
      var obj2 ={}
      
      obj1.foo(2)
      console.log(obj1.a) //2
      
      var bar = new obj1.foo(4)
      console.log(obj1.a) //2
      console.log(bar.a) //4 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      可以看到 new綁定的優(yōu)先級(jí)比隱式綁定要高

      new 綁定跟顯示綁定比較

      new跟call apply無(wú)法一起使用 無(wú)法通過(guò)new foo.call(obj),試一下硬綁定

      在這里插入代碼片 
      
      • 1
      function foo(arg){
          this.a = arg
      }
      var obj1 ={}
      var bar = foo.bind(obj1)
      bar(3)
      console.log(obj1.a) //3
      
      var baz = new bar(4)
      console.log(baz.a) //4
      console.log(obj1.a) //3 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      new 調(diào)用bar修改了硬綁定時(shí)候的 函數(shù)的this new的優(yōu)先級(jí)高一點(diǎn)

      所以我們可以根據(jù)下面的優(yōu)先級(jí)規(guī)則進(jìn)行判斷了

      1.函數(shù)是否在new中調(diào)用 是的話this綁定新創(chuàng)建的對(duì)象 var bar = new Foo()
      2.函數(shù)是否通過(guò)call apply 顯示綁定或者是 bind硬綁定 如果是的話this指向指定的對(duì)象 foo.call(obj)
      3.函數(shù)是否在某個(gè)上下文中調(diào)用 隱式綁定,如果是 this綁定那個(gè)上下文對(duì)象 注意綁定丟失的問(wèn)題
      4.如果都不是 就是默認(rèn)綁定非嚴(yán)格模式下綁定的是全局對(duì)象 嚴(yán)格模式下綁定的是undefined

      綁定例外

      1.將null和undefined作為call apply參數(shù) 作為this綁定對(duì)象的時(shí)候 這些值會(huì)被忽略 應(yīng)用的是默認(rèn)綁定

      var a =3
      function foo(){
          console.log(this.a) //3
      }
      foo.call(null) 
      
      • 1
      • 2
      • 3
      • 4
      • 5

      2.箭頭函數(shù)

      function foo(){
          return ()=>{
              console.log(this.a)
          }
      }
      var obj1 = {
          a:3
      }
      var obj2 = {
          a:4
      }
      var bar = foo.call(obj1)
      bar.call(obj2) //3  this綁定的是obj1 而不是obj2!!! 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      在看一個(gè)

      function foo(){
          setTimeout(()=>{
              console.log(this.a) //2
          },100)
      }
      var obj = {
          a:2
      }
      foo.call(obj) 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      箭頭函數(shù)不使用this綁定的四種規(guī)則,而是根據(jù)外層作用域來(lái)決定this的,外層作用域的this綁定的是什么 他的this就是什么





      轉(zhuǎn)自:csdn 論壇 作者:Selfimpr歐

      藍(lán)藍(lán)設(shè)計(jì)www.tuitetiyu.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)

      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 五月综合激情婷婷六月色窝| 欧美线在线精品观看视频 | 亚洲愉拍国产自91| 亚洲精品动漫卡通在线观看| 久久久精彩国产片| 精品无码一区在线观看| 亚洲成在人线a免费 | 亚洲欧美精品中文一区二区三区| 中文字幕人妻无码系列第三区| 亚洲中文字幕日产无码| 无码人妻精品一区二区三区蜜桃91| 国产成人无码精品久久久APP| HEYZO无码综合国产精品227| 亚洲国产色欲AV一级毛片片| 中文字幕无码一线二线三线| 欧美黑人疯狂性受XXXXX喷水| 亚洲av无码兔费综合| 久久精品国产亚洲一区二区| 久久久噜噜噜久久免费| 亚洲人妻无码在线| 九九无码人妻一区二区三区 | 久久精品只有精品96| 人妻少妇久久久久久97人妻| 国产百度云网曝门在线观看| 国产真人无打码作爱免费视频| 亚洲欧美日韩国产精品二区| 侯马市| 中文字幕精品免费| 日日摸夜夜摸狠狠摸中文字幕| 久久久久久精品一级毛片外国| 亚洲老妈激情一区二区三区| 中文亚洲精油按摩色偷偷AV| 99久久精品午夜一区二区| 国产丝袜美女一区二区三区| 亚拍一区 在线视频系列| 最近中文2018字幕在线观看| 欧美疯狂XXXX乱大| 综合一区久久k极品视觉盛宴| 99久久久无码国产精品古装| 精品久久久久久久久久中文字幕| 精品一久久香蕉国产线看观|