1. 程式人生 > 其它 >js函式--this使用詳情

js函式--this使用詳情

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函式--this使用詳情</title>
</head>
<body>
    <script>
        /*
            javascript函式--this使用詳情:
                面嚮物件語言中 this 表示當前物件的一個引用。
                    但在 JavaScript 中 this 不是固定不變的,它會隨著執行環境的改變而改變。
                    在方法中,this 表示該方法所屬的物件。
                    如果單獨使用,this 表示全域性物件。
                    在函式中,this 表示全域性物件。
                    在函式中,在嚴格模式下,this 是未定義的(undefined)。
                    在事件中,this 表示接收事件的元素。
                類似 call() 和 apply() 方法可以將 this 引用到任何物件。
                在絕大多數情況下,函式的呼叫方式決定了 this 的值(執行時繫結)。
                ES2015 引入了箭頭函式,箭頭函式不提供自身的 this 繫結(this 的值將保持為閉合詞法上下文的值)。
        */
        /*
            1.this指向全域性物件
            2.this指向所屬物件
            3.this.指向物件例項
            4.this指向call()函式、apply()、bind()函式呼叫後重新繫結的物件。
            5.箭頭函式
        */

        //1.this指向全域性物件或undefined
            /*
                當函式沒有所屬物件而直接呼叫時,this指向的是全域性物件。

                在函式中,在嚴格模式下,this 是未定義的(undefined)。
            */
           var value=10;
           var obj ={
               value:100,
               method:function(){
                   var foo=function(){
                       console.log(this.value);//10
                       console.log(this);//Window物件
                   };
                   foo();
                   return this.value;
               }
           };
           obj.method();

           //嚴格模式
           var obj1 ={
               method:function(){
                   var foo=function(){
                    "use strict"; // 這裡是嚴格模式
                       console.log(this);//undefined
                   };
                   foo();
                   return this.value;
               }
           };
           obj1.method();
           

        //2.this指向所屬物件
           /*
                this指向呼叫物件
           */
          //沿用上函式
          /*obj.method()的返回值是this.value,method()的呼叫體為obj此時this指向obj,輸出obj.value,輸出100*/

          console.log(obj.method());//100

        //3.this.指向物件例項
           /*
                當通過new操作符呼叫建構函式生成物件的例項時,this指向該例項。
           */

          //全域性變數
          var number=10;
          function Person(){
              //複寫全域性變數
              number=20;
              //例項變數
              this.number=30;
          }
          //原型函式
          Person.prototype.getNumber=function(){
              return this.number;
          };
          //通過new操作符獲取物件的例項
          var p=new Person();
          console.log(p.getNumber());//30


        //4.this指向call()函式、apply()、bind()函式呼叫後重新繫結的物件。(後有詳解)
          //4.1 call、apply()

          function add(c, d) {
            return this.a + this.b + c + d;
            }

            var o = {a: 1, b: 3};

            // 第一個引數是用作“this”的物件
            // 其餘引數用作函式的引數
            add.call(o, 5, 7); // 16

            // 第一個引數是用作“this”的物件
            // 第二個引數是一個數組,陣列中的兩個成員用作函式引數
            add.apply(o, [10, 20]); // 34

          //4.2 bind
            /*
                ECMAScript 5 引入了 Function.prototype.bind()。
                呼叫f.bind(someObject)會建立一個與f具有相同函式體和作用域的函式,
                但是在這個新函式中,this將永久地被繫結到了bind的第一個引數,無論這個函式是如何被呼叫的。
            */
            function f(){
            return this.a;
            }

            var g = f.bind({a:"azerty"});
            console.log(g()); // azerty

            var h = g.bind({a:'yoo'}); // bind只生效一次!
            console.log(h()); // azerty

            var o = {a:37, f:f, g:g, h:h};
            console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty

        //5.箭頭函式
            /*
                在箭頭函式中,this與封閉詞法環境的this保持一致。
                在全域性程式碼中,它將被設定為全域性物件
            */
            var globalObject = this;
            var foo = (() => this);
            console.log(foo() === globalObject); // true

    </script>
</body>
</html>