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指向就會給改變。複製代碼
相關文章
相關標籤/搜索