javascript中的apply和call簡介

在javascript中上下文作用域是一個比較復雜的東西,而apply和call就能讓方法的上下文發生改變。

apply的用法:

function.apply(thisobj,args)

thisobj:調用function方法的作用域,在function方法中this表示

args:function的參數,是一個數組,數組中的每個元素代表function的一個參數。

先看一下下面的代碼:

        var Dog = function(name){
            this.name = name;
        }

        Dog.prototype.say=function(word){
            alert(this.name+":"+word);
        }

        var dog1 = new Dog("dog1");
        var dog2 = new Dog("dog2");
        dog1.say("你好啊。");   //dog1:你好啊。
        dog1.say.apply(dog2,["我很不好。"]); //dog2:我很不好。通過 dog2.say.apply(dog2,["我很不好。"]),可以把say方法中的this作用域變成dog2。

當在setTimeout和setInterval中apply這種改變this作用域的方式就有用處瞭

就上面的代碼改造:讓調用say的時候過200毫秒後執行alert(this.name+":"+word);

如果代碼改寫成:

        var Dog = function(name){
            this.name = name;
        }

        Dog.prototype.say=function(word){
            setTimeout(function(){
                alert(this.name+":"+word);
            },200);

        }

        var dog1 = new Dog("dog1");
        var dog2 = new Dog("dog2");

        dog1.say("你好啊。");   //:你好啊。這樣的話this.name就變成空瞭,因為this的作用域變成瞭Window對象瞭。

所以可以用apply的方法把this作用域換回dog1,如下:

        var Dog = function(name){
            this.name = name;
        }

        Dog.prototype.say=function(word){
            setTimeout(function(word){alert(this.name+":"+word);}.call(this,word)
                ,200);
        }        dog1.say("你好啊。");   //dog1:你好啊。這樣就能實現該功能瞭。

當然最好的方式還是使用javascript的閉包。

上面的apply完全可以用call來重寫。

call用法:

function.call(thisobj,arg1,arg2,…)

thisobj:調用function方法的作用域,在function方法中this表示

arg1,arg2,…:function的參數(與apply不同的是,call是一個一個寫出來,而apply則是數組)

用call改造:

        var Dog = function(name){
            this.name = name;
        }

        Dog.prototype.say=function(word){
            setTimeout(function(word){alert(this.name+":"+word);}.call(this,word)
                ,200);
        }

        var dog1 = new Dog("dog1");
        var dog2 = new Dog("dog2");

        dog1.say("你好啊。");   //dog1:你好啊。
        dog1.say.call(dog2,"我很不好。"); //dog2:我很不好。

發佈留言