函数调用上下文的三种方式Function.prototype.call Function.prototype.apply Function.prototype.bind

1.函数的三种执行方式(this的指向) ->注意:共同是this的执向是确定的无法修改

1.回调函数: 如果一个函数的参数是一个函数,这个参数函数叫做回调函数
2.自调用函数: 如果一个函数自己调用自己,这个函数称之为自调用函数 (匿名函数)()
2-1.任何函数都可以使用自调用函数的语法
2-2.一般情况下都是匿名函数自调用
2-3.匿名函数自调用作用: 开辟局部作用域,避免全局变量污染
3.构造函数: 如果一个函数调用的时候使用了new关键字,这个函数称之为构造函数
注意:定时器的this指向的是window
   <script>
        /*1.函数三种调用方式: 全局函数   对象方法  构造函数
          
          2.this:谁 `调用` 我,我就代表谁
               全局函数: this指向window
               对象方法: 对象
               构造函数new : this指向new创建的对象

        3.注意点: 定时器:this指向window
        
         */

        //1.全局函数
         function fn(){
             console.log('11111');
             console.log(this);
         };

         //this:指向window  因为fn全局函数是window的一个属性
         fn();//window.fn()


         //2.对象的方法
         var person = {
             name:'张三',
             age:18,
             sayHi:function(){
                 console.log(this);
                 console.log('我是张三');
             }
         };

/* 容易混淆点: this的指向取决于函数的调用。不要看函数是怎么声明的,要看函数怎么调用的 */
         //2.1 peroson对象调用sayHi
         person.sayHi();

         //将fn函数赋值给对象的sayHi
         person.sayHi = fn;
         //此时调用sayHi,就会执行fn中的代码。  但是fn这个代码是经过person对象来调用的
         person.sayHi();//this:person


         //3.构造函数:其实就是普通的函数
         function Student(name,age){
             this.name = name;
             this.age = age;
         };

         //3.1 使用new调用:调用构造函数:new会做四件事     this:new创建的对象
        var s1 = new Student('大王',20);

        //3.2 没有用new:就是普通函数
        var s2 = Student('小白',33);
        console.log(s2);//undefined

        console.log(age);//33
        console.log(name);//小白
        
        //4.特殊情况:定时器中的回掉函数:this指向window
        setTimeout(function(){
            console.log(this);//window
        },1000);
    </script>

2. 函数的上下文调用(第四种调用方式) -> 可以动态修改this的指向

上下文调用模式:可以动态修改this的指向
三种语法异同点:
相同点: 作用都是动态修改this
不同点:传参方式不一样
1.call(): 函数名.call(修改后的this,arg1,arg2,arg3………………)
2.apply(): 函数名.apply(修改后的this,[arg1,arg2,arg3…………])
3.bind(): 函数名.bind(修改后的this)
3-1. 不会立即执行函数,而是返回修改this之后的新函数
3-2.一般用于回掉函数(定时器)
 //1.修改this指向:三种方式无法修改
        //  function fn(){
        //      //this = {name:'张三',age:18};//报错,this无法修改
        //      console.log(this);
        //      console.log('111');
        //  };
        //  fn();


         //2.需求:修改this指向
         //上下文调用模式:修改this指向

         //2.1  call()
         //语法:  函数名.call(修改的this指向,arg1,arg2,arg3,………………)

         function fn1(a,b){
             console.log(this);
             console.log(a+b);
         };
         fn1();//this:window
         fn1.call({name:'张三',age:18},10,20);
               
         //2.2 apply()
         //语法:  函数名.apply(修改的this指向, [数组或伪数组])
         function fn2(a,b){
             console.log(this);
             console.log(a+b);
         };
         fn2(100,200);//this:window
         fn2.apply({age:88},[20,30]); //自动遍历数组或伪数组的每一个元素给函数的形参赋值
         
         //2.3  bind()
         //语法:  函数名.bind(修改的this指向,arg1,arg2,arg3,…………)
         //bind() : 不会执行这个函数,而是会返回一个修改了this之后的新函数
         function fn3(a,b){
             console.log(this);
             console.log(a+b);
         };
        var newFn3 =  fn3.bind([1,2,3])
        newFn3(50,100);//newFn3是bind方法返回的函数,所以this变成了bind方法修改后的this指
        //bind修改this指向一般用于回调函数(定时器)
         //定时器this:默认指向window
         //setTimeout(回调函数,时间间隔)

         //(1)具名函数
         var test = function(){
             console.log('111');
             console.log(this);  
         };

        //  var newTest = test.bind([1,2,3]);
        // setTimeout(newTest,2000);
        setTimeout(test.bind([1,2,3]),2000);

        //(2)匿名函数
        setTimeout(function(){
            console.log(this);
        }.bind([10,20,30]),3000);

芹丸子
40 声望4 粉丝

所有文章都是自己的学习记录,如果对你有帮助我很荣幸,如果文章记录之处有什么不对不好的地方还请指教