资讯专栏INFORMATION COLUMN

比较call( ) apply( ) bind( )

cheng10 / 1605人阅读

摘要:简单比较一下与和的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过来获得对它的引用。而则会立即执行函数。

简单比较一下call() apply() bind()

《JavaScript: The Definitive Guide》

call()与apply()

call()和apply()的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用。简单来说就是把一个方法绑定到一个对象上去调用:

栗如,要想以对象o的方法来调用函数f():

f.call(o);
f.apply(o);

其实相当于:

o.m = f; //将f存储为o的临时方法
o.m(); //调用它,不传入参数
delete o.m; //将临时方法删除

--> 对于call(),第一个实参之后的所有实参就是要传入待调用函数的值。栗如:

//以对象o的方法的形式调用函数f(),并传入两个参数
f.call(o, 1, 2);

--> 对于apply(),它的实参都放入一个数组当中:

f.apply(o,[1, 2]);

给apply()传入的参数数组可以是任意长度的,栗如:

//找出一个数组中最大的数值元素
var biggest = Math.max.apply(Math, array_of_numbers);

传入apply()的参数数组可以是类数组对象也可以是真实数组。实际上,可以将当前函数的arguments数组直接传入apply()来调用另一个函数:

//将对象o中名为m的方法替换为另一个方法
//可以在调用原始方法之前和之后记录日志消息
function trace(o, m) {
    var original = o[m];//在闭包中保存原始方法
    o[m] = function() {//定义新的方法
        console.log(new Date(), "Entering", m);
        var result = original.apply(this, arguments);//调用原始函数
        console.log(new Date(), "Exiting", m);
        return result;
     };
}
//这个新方法是包裹原始方法的另一个泛函数 (monkey-patching)?
bind() 方法

bind()是ES5中的方法。
当在函数f()上调用bind()方法并传入一个对象o作为参数,这个方法将返回一个新的函数,(以函数调用的方式)调用新的函数将会把原始的函数f()当作o的方法来调用。传入新的函数的任何实参都讲传入原始函数。栗如:

function f(y) { return this.x + y; }
var o =  { x: 1 };
var g = f.bind(o);
g(2); //=> 3

可以用ES3简单模拟:

function bind(f, o) {
    if(f.bind) return f.bind(o);
    else return function() {
        return f.apply(o, arguments);
    }
}

然而,bind()方法不仅仅是将函数绑定至一个对象----除了第一个参数外,传入bind()的实参也会绑定至this,这个附带的应用是一种常见的函数式编程技术,也被称为“柯里化“。

function f(y, z) { return this.x + y + z }
var g = f.bind({ x: 1 }, 2);
g(3);//=> 6 this.x绑定到1, y绑定到2, z绑定到3

如果用ES3模拟:

if(!Function.prototype.bind){
    Function.prototype.bind = function(o /*, args*/){
        //将this和arguments的值保存至变量中
        //以便在后面嵌套的函数中可以使用它们
        var self = this, boundArgs = arguments;
        
        //bind方法的返回值是一个函数
        return function(){
            //创建一个实参列表,将传入bind()的第二个及后续的实参传入这个参数
            var args = [], i;
            for(i=1; i

http://web.jobbole.com/83642/
深入浅出妙用 Javascript 中 apply、call、bind

一个比较

var obj = {
    x: 81,
};
 
var foo = {
    getX: function() {
        return this.x;
    }
}
 
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。

也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

一个总结

apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;

apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

apply 、 call 、bind 三者都可以利用后续参数传参;

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

一道题:

定义一个 log 方法,让它可以代理 console.log 方法

function log(){
    console.log.apply(console, arguments);
}

若要给每一个 log 消息添加一个”(app)”的前辍?

//该怎么做比较优雅呢?这个时候需要想到arguments参数是个伪数组,通过 //Array.prototype.slice.call 转化为标准数组,再使用数组方法unshift
function log(){
    var args = Array.prototype.slice.call(arguments);
    args.unshift("(app)");
    console.log.apply(console, args);
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82171.html

相关文章

  • JS中的callapplybind方法详解

    摘要:不能应用下的等方法。首先我们可以通过给目标函数指定作用域来简单实现方法保存,即调用方法的目标函数考虑到函数柯里化的情况,我们可以构建一个更加健壮的这次的方法可以绑定对象,也支持在绑定的时候传参。原因是,在中,多次是无效的。 bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。 apply、call 在 javascript 中,call 和 apply 都是...

    zombieda 评论0 收藏0
  • JS基础篇--callapplybind方法详解

    摘要:首先我们可以通过给目标函数指定作用域来简单实现方法保存,即调用方法的目标函数考虑到函数柯里化的情况,我们可以构建一个更加健壮的这次的方法可以绑定对象,也支持在绑定的时候传参。原因是,在中,多次是无效的。而则会立即执行函数。 bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。 apply、call 在 javascript 中,call 和 apply 都是...

    lastSeries 评论0 收藏0
  • bind()、call()、apply()理解及用法

    摘要:首先,我们判断是否存在方法,然后,若不存在,向对象的原型中添加自定义的方法。指向调用它的对象。总之三个的使用区别都是用来改变函数的对象的指向的第一个参数都是要指向的对象都可以利用后续参数传参是返回对应函数,便于稍后调用,是立即调用 apply和call都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向),Function对象的方法,每个函数都能调用; 使用a...

    hoohack 评论0 收藏0
  • JavaScript函数的callapplybind

    摘要:它们有明确的和成员函数的定义,只有的实例才能调用这个的成员函数。用和调用函数里用和来指定函数调用的,即指针的指向。同样,对于一个后的函数使用或者,也无法改变它的执行,原理和上面是一样的。 函数里的this指针 要理解call,apply和bind,那得先知道JavaScript里的this指针。JavaScript里任何函数的执行都有一个上下文(context),也就是JavaScri...

    alighters 评论0 收藏0
  • js 面试官想了解你有多理解call,apply,bind?

    摘要:返回值这段在下方应用中有详细的示例解析。回调函数丢失的解决方案绑定回调函数的指向这是典型的应用场景绑定指向,用做回调函数。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this...

    wuaiqiu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<