iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
0
Modern Web

一步一腳印-紮紮實實學es6系列 第 18

函數(7) apply()

  • 分享至 

  • xImage
  •  

apply(thisarg,[arg1,arg2,arg3,...])

與 call() 的差別是thisarg 之後的參數,可以放進陣列

以功能上來說

幾乎是沒什麼差異的

在這邊來試驗一下這個功能

不傳參數時,表現跟call 一樣

都是改變this指向,並且呼叫一次這個函式
我們將上一篇的程式拿來修改看看
只將call 改成apply 看看是否如預期

var spritePokemon={name:'pikachu'}
function run(obj,action){
    obj.xLocation=100;
    action.call(obj); // 在這邊使用apply將action 這個callback 函式的this 綁到obj身上
}


(function jumpAndRun(sprite){
    run(sprite,function(){
        console.log(this)// 因為run有將aciton.apply指向obj,所以這邊會指向sprite
        this.yLocation=200;
    });
})(spritePokemon);

console.log(spritePokemon);

https://ithelp.ithome.com.tw/upload/images/20181018/20110579u177DvKiwV.png

結果果然一模一樣
那我們要測試不同的地方,就是call的thisarg ,後面是一個一個傳參數進去
而apply 可以直接傳陣列,但效率也會比call 慢一些
call 傳參數

var spritePokemon={name:'pikachu'}
function run(obj,action){
    obj.xLocation=100;
    action.call(obj,3,4); // 在這邊使用apply將action 這個callback 函式的this 綁到obj身上
}


(function jumpAndRun(sprite){
    run(sprite,function(shiftX,shiftY){
        console.log(this)// 因為run有將aciton.apply指向obj,所以這邊會指向sprite
        this.yLocation=200+shiftY;
		this.xLocation+=shiftX;
    });
})(spritePokemon);

console.log(spritePokemon);

apply 傳陣列
以下程式只有改apply的參數傳遞

var spritePokemon={name:'pikachu'}
function run(obj,action){
    obj.xLocation=100;
    action.apply(obj,[3,4]); // 在這邊使用apply將action 這個callback 函式的this 綁到obj身上
}


(function jumpAndRun(sprite){
    run(sprite,function(shiftX,shiftY){
        console.log(this)// 因為run有將aciton.apply指向obj,所以這邊會指向sprite
        this.yLocation=200+shiftY;
		this.xLocation+=shiftX;
    });
})(spritePokemon);

console.log(spritePokemon);

由此可知效果是相同的

但是效率不太一樣,以下我們來測試看看
先來看看慢的apply

var spritePokemon={name:'pikachu'}
function run(obj,action){
    obj.xLocation=100;
    action.apply(obj,[3,4]); // 在這邊使用apply將action 這個callback 函式的this 綁到obj身上
}


var jumpAndRun=function (sprite){
    run(sprite,function(shiftX,shiftY){
       // console.log(this)// 因為run有將aciton.apply指向obj,所以這邊會指向sprite
        this.yLocation=200+shiftY;
		this.xLocation+=shiftX;
    });
}

//跑五輪測試
for(var i=0;i<5;i++){
	console.time('apply');//計時開始
	for(var j=0;j<100000000;j++)
    {
		jumpAndRun(spritePokemon);
	}
	console.timeEnd('apply')//計時結束
}

結果
https://ithelp.ithome.com.tw/upload/images/20181019/201105798H3ysWVFSg.png

那麼換上call參戰的結果呢...?

var spritePokemon={name:'pikachu'}
function run(obj,action){
    obj.xLocation=100;
    action.call(obj,3,4);
}


var jumpAndRun=function (sprite){
    run(sprite,function(shiftX,shiftY){
       
        this.yLocation=200+shiftY;
		this.xLocation+=shiftX;
    });
}

//跑五輪測試
for(var i=0;i<5;i++){
	console.time('call');//計時開始
	for(var j=0;j<100000000;j++)
    {
		jumpAndRun(spritePokemon);
	}
	console.timeEnd('call')//計時結束
}

https://ithelp.ithome.com.tw/upload/images/20181019/20110579KcaTwDYVHX.png

發現call 要快上許多, 不過平時不會一直做這件事,算是冷知識...


上一篇
函數(6) call()
下一篇
closure 閉包(1)
系列文
一步一腳印-紮紮實實學es630
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言