爲何要使用call,apply,bind數組
先看一個普通的對象:app
var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } obj.say();//大雄你好我是多啦A夢
咱們對上面的函數作一些調整:函數
var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } var fn = obj.say; fn();//大雄你好我是
這個時候不會再輸出「大雄你好我是多啦A夢」由於在第二個例子中this已經不是obj而變成了window而window中並無name屬性。this
爲了可以達到預期的結果,咱們可使用call,apply或者bind來改變函數執行時this的指向:spa
var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } var fn = obj.say; fn.call(obj);//大雄你好我是多啦A夢
在咱們平時的開發中要充分利用call,apply,bind,這三個函數均可以改變函數運行時this的指向,當時他們也有一些不一樣,call和apply會當即執行函數,bind則是建立一個新的函數,更改新函數的this的指向。prototype
call,applycode
首先call和apply在咱們平時的開發中有兩個妙用:對象
Array.prototype.slice.call(obj)-->obj是一個類數組,經過這個函數能夠把類數組轉換成一個真正的數組(參數位置就是類數組)。blog
Object.prototype.toString.call(arg)-->arg能夠是任意一種類型的值,這個函數最精確的判斷出參數的類型。開發
call,apply在使用時會修正函數運行時this的指向,而且會當即執行函數。在只接受一個參數時兩個函數的使用方式是同樣的,使用方式以下:
//call使用 var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } var fn = obj.say; fn.call(obj); //apply使用 var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } var fn = obj.say; fn.apply(obj);
call和apply這兩個函數在使用時也是有一些不一樣的,這個咱們稍後再介紹。
bind
bind函數在使用是是建立一個新的函數,修改新函數運行時this的指向。
var obj = {}; obj.name = "多啦A夢"; obj.say = function(){ console.log("大雄你好我是"+this.name); } var fn = obj.say.bind(obj); fn();
若是函數中須要參數則把參數放在bind的第二個參數以及後。
var skin= "藍皮膚"; var eye = "大眼睛"; var obj = {}; obj.name = "多啦A夢"; obj.say = function(skin,eye){ console.log("大雄你好我是"+skin+eye+"的"+this.name); } var fn = obj.say.bind(obj,skin,eye); fn();
call
call基本的使用方法咱們已經知道,當call函數須要使用多個參數是和bind函數是同樣的,第一個參數必須表明this的指向,若是原函數須要參數,則參數放在第二個及之後。
var skin= "藍皮膚"; var eye = "大眼睛"; var obj = {}; obj.name = "多啦A夢"; obj.say = function(skin,eye){ console.log("大雄你好我是"+skin+eye+"的"+this.name); } var fn = obj.say; fn.call(obj,skin,eye);
apply
apply函數最多能夠接收兩個參數,第一個參數表示this的指向,第二個參數必須是一個數組或者類數組,數組的每個元素表示原函數須要使用的參數
var skin= "藍皮膚"; var eye = "大眼睛"; var obj = {}; obj.name = "多啦A夢"; obj.say = function(skin,eye){ console.log("大雄你好我是"+skin+eye+"的"+this.name); } var fn = obj.say; fn.apply(obj,[skin,eye]);
apply在咱們不肯定參數的個數時會變得很是有用,好比咱們簡化console.log函數咱們能夠這樣:
function print(arg){ console.log(arg); } print("hello"); //console.log是能夠接收多個參數的因此爲了更加符合console.log函數的特性咱們能夠稍加改造 function print(){ console.log.apply(this,arguments); } print("hello",1,true);