• <center id="sm46c"></center>
  • <dfn id="sm46c"></dfn>
  • <strike id="sm46c"></strike>
  • <cite id="sm46c"><source id="sm46c"></source></cite>
    • <strike id="sm46c"><source id="sm46c"></source></strike>
      <option id="sm46c"></option>
      国产精品天天看天天狠,女高中生强奷系列在线播放,久久无码免费的a毛片大全,国产日韩综合av在线,亚洲国产中文综合专区在,特殊重囗味sm在线观看无码,中文字幕一区二区三区四区在线,无码任你躁久久久久久老妇蜜桃

      this解析 記錄分享

      2021-4-22    前端達人

      this指向的問題也是JavaScript中的難點之一了,也是面試常問的問題,很多時候對this指向的問題就很懵逼,明明應該是指向他,為什么又指向他了…所以我就學習了一下這方面的知識,整理了一下,希望能夠幫助大家

      為什么要用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

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

      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

      就像這樣,這樣看起來就不想上面那樣簡潔了,你要把一個對象傳來傳去的

      認識this

      剛見到this的時候 覺得this指向是這個函數自身,或者是函數的作用域,后來發現其實不是這樣的的,不過也不能說錯了,因為有些情況確實是這樣的,比如這樣:

      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

      無法指向函數作用域

      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

      我們要記住非常重要的一點:this是在運行的時候進行綁定的,而不是在定義的時候綁定,this的綁定跟函數聲明的位置沒有關系,主要是取決于函數的調用方式,想要找到this指向誰,我們就要看懂函數是怎么調用的。

      綁定規則

      1.默認綁定

      當一個獨立函數正常調用的時候,不帶任何修飾的調用

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

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

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

      嚴格模式下 this不會指向全局對象 this綁定的是undefined

      2.隱式綁定

      調用位置上是否有上下文對象

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

      調用位置會使用obj上下文對象來引用函數,foo被調用的時候 他的落腳點指向是obj對象,隱式綁定的規則就會把this指向這個上下文對象。所以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

      當多層調用的時候 只有最后一層才會影響函數的調用位置 比如上面這個 this綁定的還是 obj 而不是obj2

      注意

      隱式綁定會出現隱式丟失的問題,會失去綁定對象,最后應用默認綁定

      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的一個引用 他引用的是foo函數本身,此時bar就是一個不帶任何修飾的函數調用 應用默認綁定

      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

      參數傳遞也是一種隱式賦值,回調函數丟失this是非常常見的…

      3.顯式綁定

      隱式綁定的時候我們必須在一個對象內部包含一個指向函數的屬性,然后通過屬性間接引用函數,把這個this間接隱式的綁定到這個對象上
      如果我們不想在對象內部包含函數的引用 ,而想在某個對象上強制調用函數
      我們可以把這個函數綁定到對象的原型上,也算是不用再對象內部包含函數了吧…
      更好的辦法是我們可以使用函數的 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

      如果你第一個參數傳入的是一個原始類型 比如字符串 布爾 數字作為綁定對象 這些原始類型會被轉換為 對象的形式 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)  //會返回一個硬編碼的新函數 他會把參數設置為this的上下文
      bar.call(obj2) //2  返回的新函數 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

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

      4.new綁定

      使用new 來調用函數的時候會執行以下操作
      1.創建一個全新的對象
      2.這個新對象會被執行原型的鏈接
      3.新對象會綁定到函數調用的this
      4.如果沒有返回其他的對象,那么函數會自動返回這個對象

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

      使用new 來調用Foo函數 會構造一個新對象并把它綁定到Foo調用中的this上 然后返回了

      優先級

      函數不帶任何修飾的時候單獨調用才會觸發默認綁定 所以說默認綁定是優先級最低的了

      那剩下三個規則哪個的優先級最高?

      顯示綁定跟隱式綁定比較

      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

      可以看到 顯示綁定的優先級還是更高一點

      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綁定的優先級比隱式綁定要高

      new 綁定跟顯示綁定比較

      new跟call apply無法一起使用 無法通過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 調用bar修改了硬綁定時候的 函數的this new的優先級高一點

      所以我們可以根據下面的優先級規則進行判斷了

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

      綁定例外

      1.將null和undefined作為call apply參數 作為this綁定對象的時候 這些值會被忽略 應用的是默認綁定

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

      2.箭頭函數

      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

      在看一個

      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

      箭頭函數不使用this綁定的四種規則,而是根據外層作用域來決定this的,外層作用域的this綁定的是什么 他的this就是什么





      轉自:csdn 論壇 作者:Selfimpr歐

      藍藍設計www.li-bodun.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服

      日歷

      鏈接

      個人資料

      藍藍設計的小編 http://www.li-bodun.cn

      存檔

      主站蜘蛛池模板: 亚洲精品久久久久国色天香| 岛国岛国免费v片在线观看| 中文字幕日韩精品东京热| 久久久噜噜噜www成人网| 少妇av射精精品蜜桃专区| 日本国产在线观看| 99热精国产这里只有精品| 国产精品十八禁在线观看 | 99久久国产综合精品麻豆| 东方四虎在线观看av| jizzjizz日本高潮喷水| 国产精品无码一区二区桃花视频 | 色欲AV伊人久久大香线蕉影院| 夜夜春久久天堂亚洲精品| 九九热精品视频在线| 久视频久免费视频久免费| 色香欲天天影视综合网| 亚洲男人av香蕉爽爽爽爽| 精品久久久久久中文墓无码| 中文字幕网伦射乱中文| 成人婷婷网色偷偷亚洲男人的天堂| 污网站在线观看视频| 少妇人妻无码专区视频| 亚洲色无码中文字幕| 99久久99这里只有免费费精品| 丰满少妇熟女高潮流白浆| 偷窥少妇久久久久久久久| 亚洲色大成网站www看下面| 婷婷色中文字幕综合在线| 日本乱人伦片中文三区| 国产熟女50岁一区二区| 久久精品国产亚洲AV成人毛片| 国产精品9999久久久久仙踪林| 2019亚洲午夜无码天堂| 亚洲AV无码一区二区三区ba| 午夜日韩久久影院| 99热成人精品热久久| 欧美国产在线精品17p | 久久天天躁夜夜躁狠狠ds005| 18禁真人抽搐一进一出动态图| 国产精品67人妻无码久久|