JS 中有什么办法能够改变this的指向

首先咱们要知道this指向哪里,或者说最终指向哪里?数组

咱们须要记住一句话,this永远指向最后调用他的那个对象bash

第一种是运用 call 以下:app

function f(){
        console.log(this)
    }
    var obj = {
        f
    };
    var fn = obj.f;
    obj.f(); //obj
    fn();  //window

    // fn.call(context,1,2,3,4,5,6);  call 是直接让函数执行了
    //第一个参数实用来改变函数执行时内部this指向的
    // 第二个参数即以后,都是传给fn函数的实参;
    fn.call(obj,677,443,6565);//
    fn.call([],2344);
    fn.call(1)
    Object.prototype.toString.call('') //'[object string]'
    var a = new f;
    console.log(a.toString());

    ({}).toString();
    Object.prototype.toString.call('')// ({}).tostring === Object.prototype.toString
    // 上述 call 执行时,把tostring方法中的this改为了 字符串 因此 返回的就是 字符串的数据类型
    // call 这个方法 在什么地方存放?  Function.prototype
    //  本身封装一个 call

    Function.prototype.myCall = function(context,...arg){
           //  context   就是咱们让指向的那个值,arg 是要传给对应函数的实参
           //  this  就是我们的 f2
         // this(...arg)    //能实现 让f2执行,而且把arg中的参数传给 f2
         //   怎么把f2中的 this 改为 context ???
         // context.eee()    eee 这个函数中的this  就是context;
        //  context.eee = this; // context.eee 跟咱们的 f2 是同一个函数;
        //  context.eee(...arg);
        //  delete context.eee // 为了避免再原有的对象中添加属性
         //var n = Math.random();
         var n = Symbol();
         context[n] = this;
         context[n](...arg);
         delete context[n];
    }

    function f2(a,b){
        console.log(this);
        console.log(a+b);
    }
    var obj = {
        q:123,
        w:234,
        e:345
    }
    f2.myCall(obj,3,3);
 call方法能够用来代替另外一个对象调用一个方法,
复制代码

第二种是运用apply改变this的指向dom

var obj = {
        q:123,w:234
    }
    var f = function(a,b,c,d){
        console.log(this);
        console.log(a,b,c,d)
    }
    f.call(obj,1,2,3,4);
    f.apply(obj,[1,2,3,4]);

    Math.max(2,3,4,6,8,1,7,9,2,2,7)//
    var ary = [2,6,4,7,5,3,8,3,6];
    Math.max(...ary);
    Math.max.apply(Math,ary);
    ```
    apply和call的目的是同样的,都是为了改变当中 this的指向问题 重点区别在于第二个参数
     第二个参数是一个数组或者类数组
     虽说给咱们的第二个参数是一个集合,可是函数执行的时候,参数仍是跟以前同样散乱的传过去的,而不是直接整个所有传过去。 
复制代码

第三种方法运用bind实现函数

var obj = {a:123}; var f = function(a,b,c){ console.log(this); console.log(a,b,c) } var fn = f.bind(obj,6,5,6) console.log(fn);this

var f2 = (a)=>{
    console.log(this)
    return a;
}
f2(); // window
f2.call(obj); //window 

// Function.prototype.myBind = function(context,...arg){
//      //  this 是f2
//      var _this = this;  // _this 这个变量存储的就是f2函数
//     return function (){
//         // console.log(this)
//         // _this()
//         //_this.call(context,...arg)
//         _this.apply(context,arg)

//     }
// }
Function.prototype.myBind = function(context,...arg){

      return (...ary)=>{
          this.call(context,...arg,...ary)
      }
}

var fn2 = f.myBind(obj,1,2,3,4); //window
// fn2 执行的时候,f2 执行 而且 f2中的 this 改为了 obj
fn2()

var fun = function(){
    console.log(arguments);
    console.log(this)
}
var fun2 = fun.bind(obj,666,777);
fun2(333,555)

bind 的用法跟第一种 call是同样的  跟一种不一样的是
不让函数当即执行,而是返回了一个新函数
返回的新函数执行的时候,this指向换掉了; 
新函数执行传递的参数会补在经过 bind绑定的参数后边
咱们能够把 bind 绑定的参数理解成新函数的默认参数
返回值是个新函数,新函数执行的时候让老函数执行了,
把老函数中的this指向就会给改变。复制代码
相关文章
相关标签/搜索