首页 > 讲真,为什么要用apply和call这两个函数?

讲真,为什么要用apply和call这两个函数?

现在很多的回答都是答这两者之间的区别,参数的不一样等等,可是我很迷糊的是为什么要用这两个函数,以及我在什么情况下会用到这两个函数,大神解答。


把一些方法转给需要用的对象


改变this的值。 我也举个例子,你已经知道他们的区别了,我就只用call 了

var obj = {'0':"zero",'1':"one",'2':'two',length:3};
// 由于 obj 不是数组,所以不可以使用 数值的方法,但是可以这样用
[].slice.call(obj,1,2);

因为 slice 的代码处理的是this这个对象的数据,所以使用call 规定了 this 的值为obj这样 slice 处理的就是这个对象了。
http://zonxin.github.io/post/...

再一段关于继承的吧(例子而已,实际不要考虑实用)

function Person(name){ this.name = name;}
function Student(name,stuID)
{
    Person.call(this,name);
    this.stuID = stuID;
}
var stu = new Student("Tom","id1");
console.dir(stu)

改变this的指向


举个例子:

var ary = [1,2,3,4]
Array.prototype.slice.apply(ary,[1,3]) //[2, 3]
Array.prototype.slice.calll(ary,1,3)  //[2, 3]
ary.slice(1,3)  //[2, 3]

举个设计模式中单例模式的例子:

var getSingle = function( fn ){
    var result;
    return function(){
        return result || ( result = fn .apply(this, arguments ) );
    } 
};

说白了就是“拿来主义”、“借刀杀人”的功效,比如我想做什么事,我不会不要紧,只要有人会就可以实现。在程序里面就是,现在假如你想用什么方法,但是当前对象没有,你可以选择拓展,自己造一个这样的方法,但是你也可以直接拿来用。比如我想封装一个工具类,想实现each方法,那我是不是一定要自己去写呢?我们可以找现成的方法进行拓展:

var utils = {
    each: function(obj, fn){
        Array.prototype.forEach.call(obj, function(item){
            fn.call(item, item);
        })
    }
}

我们可以选择直接使用Array的forEach方法,但是如果直接使用forEach方法,必须是一个数组或者类数组对象才能调用,比如:

var arr = [1,2,3];
arr.forEach(function(item){
    console.log(item);
})

但是有时候我们希望这样用:

utils.each(arr,function(item){
    console.log(item);
})

那么我们就可以使用上面说的通过call拓展咯!

有时候这样使用更方便,我们只需要对象和回调方法即可,按照一般的说法就是:call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。

看很多人说了call和apply的用法,但是好像还是没有说为啥要这样,最后补充一下:

如果说到call/apply的作用,很多时候我们是用来实现继承,JavaScript在es6之前没有想其他语言一样的继承机制,但是可以用很多方法去变式实现,如对象冒充、原型链方式,call/apply方式,es6中的Class。

如上面那个例子中,通过call方法,从Array中继承了forEach方法。

【热门文章】
【热门文章】