看完视频后,https://www.bilibili.com/video/BV167411v7bB?p=1  的总结。

this的指向:

  1.默认绑定,            分别对应函数的四种调用:  ----独立调用

  2.隐式绑定,                ----方法调用

  3.显示绑定,                ----间接调用

  4.new绑定,                 ----构造函数调用

  5.严格模式下this的指向

  6.隐式丢失。(*—*)        

1.默认绑定(本质都是独立调用嘛)-----  独立调用(this指向window)

  1>  全局环境下,this指向的window

<script type="text/javascript">
   console.log(this)   //window
</script>

  2 >  函数被独立调用时,内部的this指向window

<script type="text/javascript">
    function fn(){
         console.log(this);
    }
    fn(); //window
</script>

  3>  被嵌套的函数在独立调用的时候,this指向的是window

<script type="text/javascript">
   var a = 100; 
   var obj = {
      a : 0 ,
      hello : function(){
          function fine(){
               console.log(this.a)
          }
          fine()  //独立调用
      }
   }
   obj.hello()  //100
</script>

  4>  自执行,被嵌套的自执行,函数中的this指向window

<script type="text/javascript">
    (function (){
           console.log(this);
     })()             //window
        
    var b=100;
    function hello(){
        var b =10;
        (function fine(){   //自执行嵌套进函数内部
            console.log(this.b);       //100
        })()
    }
    hello();
</script>

  5>  闭包函数的this指向window

<script type="text/javascript">
    var k=100;
    var obj = {    
         k :0,
         hello : function(){
            function fine(){
            console.log(this); //window
            return k ;    //100
                }
            return fine()
        }
    }
    console.log( obj.hello());
</script>    

2.隐式绑定  ---- 方法调用(看调用this的对象直接指向了谁,那么this就直接指向了谁)

  1>  作为对象的方法被调用时,指向的是对象

<script type="text/javascript">
  var a = 100;
  function hello(){
    console.log(this.a);
  }
  var obj = {
    a :0,
    fine:hello,
  }
  obj.fine(); //0
</script>

  具体看清楚到底是谁在调用

<script type="text/javascript">
     var a = 100;
     function hello(){
        console.log(this.a);
     }
     var obj = {
        a :0,
        fine:hello,    
        obj2:{
           a:200,
           fine:hello
         }
     }
      obj.fine();   //0
      obj.obj2.fine(); //200
</script>

3.显示绑定  ------  间接调用

  1>  通过call() ,     apply(),   bind()  把对象绑定到this上

<script type="text/javascript">
    var a = 100;
    function hello(){
        console.log(this.a)
    }
    var obj ={
        a:0
    }
    hello(); //100 
        hello.call(obj);  //0
    hello.apply(obj); //0
       var fn = hello.bind(obj);
       fn();  //0
</script>

  2>  硬绑定 ,this不能再被改变了

<script type="text/javascript">
    var a = 100;
    function hello(){
        console.log(this.a)
    }
    var obj ={
        a:0
    }
    var bar = function(){
        hello.call(obj) //硬绑定到obj
    }
    bar(); // 0
    bar.call(window);  //0 ,不会被改变
</script>

  看懂了上面,再来看 call() ,     apply(),   bind()   的具体用法:https://www.runoob.com/w3cnote/js-call-apply-bind.html

  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

       apply()一个很强大的功能——能将一个数组默认转化为参数列表!!!

  再来思考一下:

  https://www.nowcoder.com/questionTerminal/d47b482e7148497582c7a995df51f393?f=discussion

  其中:Array.prototype.slice():

  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

  3>  js中很多内置函数也有显示绑定的作用

 

4.new绑定   -------构造函数调用  

  1>  new实例化

<script type="text/javascript">
    function fn(){
        console.log(this);
    }
    fn();      //window
    var mynew = new fn();   
    console.log(mynew);       //fn , 用new来执行函数,this指向的是当前实例化的对象即fn
</script>
<script type="text/javascript">
    var person = {   
        fav : function (){return this;} 
    }
    console.log(person.fav());   //打印的是person对象 
    var   p = new person.fav(); 
     console.log(p);//打印的是fav对象,因为实例化的是fav,this指向实例化的对象
</script>

  2>  return的对象也是实例化的对象

5.严格模式下this的指向

  1>  严格模式下,独立调用的函数内部的this指向了undefined。

  2>  严格模式下,函数apply() 和 call()内部的this始终指向它们的第一个参数。

6.隐式丢失  *—*

  被隐式绑定的函数丢失了绑定对象后,this默认绑定到window

  1>  函数别名

<script type="text/javascript">
    var a = 100;
    function fine(){
        console.log(this.a);
    }
    var obj = {
        a:0,
        hello:fine
    }
    obj.hello();   //0
    var bar =obj.hello; // bar被赋值为obj.hello。bar和obj毫无关系,this隐式丢失
    bar(); //100 ,隐式丢失,默认this指向的是window
</script>

  2>  参数传递

<script type="text/javascript">
        var a = 100;
    function hello(){
        console.log(this.a); 
    }
    function bar (fn){ 
        fn();
    }
    var obj = {
        a:0,
        fine:hello
    }
    obj.fine();  //0 , 是一个对象的方法
    bar(obj.fine);//100  把obj.fine作为参数传递,obj和bar毫无关系,this丢失了它的绑定对象,指向window
</script>        

  3>  内置函数

  ( setTimeout() 和 setInterval() 等函数,它们的第一个参数的回调函数中的this默认指向的是window )

<script type="text/javascript">
    var a =100;
    function hello(){
        console.log(this.a);
    }
    var obj = {
        a:0,
        fine:hello
    }
    setTimeout(obj.fine,1000); //100
</script>

  4>  间接调用

<script type="text/javascript">
    var a =100;
    function hello(){
        console.log(this.a);
    }
    var obj = {
        a:0,
        fine:hello
    }
    var p ={a:7};
    obj.fine();  //0
    (p.fine = obj.fine) (); // 100  立即执行,obj.fine赋值给了p的fine函数,立即执行,this指向了window.
    p.fine(); //7 , 间接调用,this指向的是调用它的对象
</script>

 

总原则:在非严格模式下,如果函数没有通过构造函数调用,直接作为普通函数使用,this指向window,在严格模式下,this指向undefined。

改变this的指向:

1>隐式绑定,调用this的对象直接指向了谁,this就指向谁。

2>显示绑定,apply,call,bind.

3>new实例化对象,this指向的是当前实例化的对象。