1.其實js中的this沒那麼難理解,當找不到this時記住一句話:
誰調我,我就指誰!new 誰指誰數組
function text1(){ console.log(this); //指window由於是window調我了 } var text2={ one:function(){ console.log(this); //指text由於text調我,我就指它! } } function text3(){ this.x=this; } var t=new text3(); t.x; //指text3 new 誰指誰
2.apply和call兩個方法的做用都是改變this的指向
來個栗子:app
function food(){} food.prototype={ color:"red", name:'apple', sayName:function(){ console.log('my name is '+this.name); } } var text1=new food(); text1.sayName();//my name is apple var banana={ name:'banana' } var pear={ name:'pear' } text1.sayName.apply(banana); //my name is banana text1.sayName.call(pear); //my name is pear
apply與call的做用徹底同樣就是接收參數的方式不一樣列如:函數
var fn=function(arg1,arg2){} apply(fn,[arg1,arg2]); call(fn,arg1,arg2);
那麼當參數,數量固定的時候用call不固定時用apply
這裏特別說下函數內的arguments對象他是一個僞數組不能直接使用push等方法
下面寫幾個栗子展現下他兩的實際用法:this
//第一個栗子追加數組 var array1=[1,2,3,4,5]; var array2=[6,7,8,9,10]; Array.prototype.push.apply(array1,array2); array1; //[1,2,3,4,5,6,7,8,9,10]
//第二個栗子求number的最大值 var numbers=[1,10,33,100,-55,423]; Math.max.apply(Math,numbers); Math.max.call(Math,1,10,33,100,-55,423);
//來個常常用到的代理console.log方法 function log(msg){ console.log(msg); } //上面是經常使用的寫法,但這樣 我傳的值是 log(1) 沒毛病 若是是log(1,2,3)呢?那就有毛病了 //他無論後面傳多少參數都會被捨棄掉只會打印1 //改進版本 function log(){ console.log.apply(console,arguments); } //這樣無論傳多少個參數都能打印出來了
bind() 方法與 apply 和 call 很類似,也是能夠改變函數體內 this 的指向。prototype
概念是:bind()方法會建立一個新函數,稱爲綁定函數,當調用這個綁定函數時,綁定函數會以建立它時傳入 bind()方法的第一個參數做爲 this,傳入 bind() 方法的第二個以及之後的參數加上綁定函數運行時自己的參數按照順序做爲原函數的參數來調用原函數。代理
var say=function(){ console.log(this.x) } var one={ x:1 } var two={ x:2 } var three={ y:3 } var fn=say.bind(one); fn()//1 var fn2=say.bind(two).bind(one).bind(three);//若是連續bind呢?結果會是什麼? fn2();//結果仍是第一個bind
緣由是,在Javascript中,屢次 bind() 是無效的。更深層次的緣由, bind() 的實現,至關於使用函數在內部包了一個 call / apply ,第二次 bind() 至關於再包住第一次 bind() ,故第二次之後的 bind 是沒法生效的。
那麼call、apply、bind三者之間的區別和應用場景是什麼呢?code
var obj={ x:81 } var text={ fn:function(){ return this.x; } } console.log(text.fn.call(obj));//81 console.log(text.fn.apply(obj));//81 console.log(text.fn.bind(obj)());//81
結果都是81,但注意的是bind()後面多了對調用的括號。
那麼總結一下:對象
apply 、 call 、bind 三者都是用來改變函數的this對象的指向的;three
apply 、 call 、bind 三者第一個參數都是this要指向的對象,也就是想指定的上下文;ip
apply 、 call 、bind 三者均可以利用後續參數傳參;
bind 是返回對應函數,便於稍後調用;apply 、call 則是當即調用 。