专注于
IT技术和业内交流

关于JS的call,apply,bind

在JS中,call、apply、bind都是用来改变this的指向的,那他们有什么区别呢?在这之前先来必须要了解上下文this。

this

this
英[ðɪs]
美[ðɪs]
pron. 这,这个; 这事,这人; 这时; 下面所说的事;
adj. 这,这个; 刚过去的,即将到来的; 今…,本…;
adv. 这样地; 就是这样; 这么地;

——摘自百度翻译。

这是this的英文意思。在JS中,this意义一样。就代表“这个”的意思。具体“这个”是指哪个呢?这个并不是在声明的时候能看出来的。只有在调用的时候,this的上下文才会体现出来“这个”是谁。例如下面代码:

var flg = 'window';
var test = {
    flg: 'test',
    fun: function(){
        console.log(this.flg);
    }
}

如上代码,this是指向哪个的?肯定不确定的!只有当我们调用的时候才能确定this上下文。如:

test.fun(); // test 这里this指向的就是test对象

var b = test.fun;
b(); // window 这里可以看成是window.b();所以this指向window

全局变量在JS中默认是挂载到window下面的,属于window的一个属性。

当然,这里只是简单的this了解,想要深入学习的童鞋自己去找this相关资料。毕竟本文的主角不是它。

改变this

开篇已经说了,这三者的作用相同,都是改变this指针。相信代码更容易理解,就不多做文字说明了。

var test1 = {
    a: 1,
    fun: function(){
        console.log(this.a);
    }
}

var test2 = {
    a: 2
}

如上代码,如何让test1中的this指向test2呢?

test1.fun.call(test2);  
test1.fun.apply(test2);
test1.fun.bind(test2);

三者实现this“转移”的代码如上。都一样?No,对于call和apply这里看上去是一样的,但是对于bind虽然实现的this的转移,但是函数并没有执行,返回的依旧是一个函数。需要test1.fun.bind(test2)();这样让返回函数执行才和call和apply的效果一致。那call和apply的区别呢?在于之后的参数形式。拿下面一个例子说明:

我们都知道function中的arguments是一个类数组对象,其实际为一个对象,但是具有数组类似的arguments[0]等取值方式。但是没有数组的slice等方式。

题目:截取arguments中的第2到4位组成的数组。显然,直接用arguments.slice(2,4)是肯定不行的。

function test(){
    var arr1 = [].slice.call(arguments,2,4);
    var arr2 = [].slice.apply(arguments, [2,4]);
    console.log(arr1,arr2); // [2,4] [2,4]
}

test(1,2,3,4,5,6);

总结

区别

call和apply在于传递参数的形式,bind和call/apply的区别在于函数是否直接执行。

PS:bind参数形式和call一致。

用途以及选择

call/apply的选择相信不用说明吧,看是否知道参数、参数形式等情况选择用call或者apply,主要用于继承,非自身原型函数调用(如上面arguments例子)等。

对于bind相信陌生一点,毕竟这个ES5才出来的东西。主要用于参数形式为函数的的函数而其本身没有立即执行的东西,以前我们经常写成var _this = this; 然后函数中用_this代替this的地方。如:

var _this = this;
$('div').onclick(function(){
    _this.XXX
});

// 可写成

$('div').onclick(function(){
    this.XXX
}.bind(this));

原生支持bind

上面也说明了bind是属于ES5的东西,对于不支持的浏览器怎么让它支持?

首先它是返回一个函数,然后要改变this指针,通过这两点可以确定代码如下:

Function.prototype.bind = function(){

    // 参数转化为说数组
    var args = [].slice.call(arguments),
        _this = this;

    //  返回一个函数
    return function(){
        // 返回函数执行结果
        return _this.apply(args[0], args.slice(1));
    }
}

未经允许,不得转载本站任何文章:代码山 » 关于JS的call,apply,bind

分享到:更多 ()

专注品牌化高端网站建设

商务服务联系我们