WEB开发者-专业的开发人员学习交流的平台 注册登录
当前位置:首页 > Web开发 > HTML5教程>

不用call和apply方法模拟实现ES5的bind方法

2017-05-03 11:46:32来源:前端小密圈作者:哥在村口等你

call()。 
2、他们的用途相同,都是在特定的作用域中调用函数。 
3、接收参数方面不同,apply()接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
4、call()方法第一个参数与apply()方法相同,但传递给函数的参数必须列举出来。

知道定义然后,直接看个简单的demo

var jawil = {
    name: "jawil",
    sayHello: function (age) {         console.log("hello, i am ", this.name + " " + age + " years old");
     }
};var  lulin = {
    name: "lulin",
};

jawil.sayHello(24);// hello, i am jawil 24 years old

然后看看使用applycall之后的输出:

jawil.sayHello.call(lulin, 24);// hello, i am lulin 24 years oldjawil.sayHello.apply(lulin, [24]);// hello, i am lulin 24 years old

结果都相同。从写法上我们就能看出二者之间的异同。相同之处在于,第一个参数都是要绑定的上下文,后面的参数是要传递给调用该方法的函数的。不同之处在于,call方法传递给调用函数的参数是逐个列出的,而apply则是要写在数组中。

总结一句话介绍callapply

call()方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。
apply()方法在使用一个指定的this值和参数值必须是数组类型的前提下调用某个函数或方法。

分析call和apply的原理

上面代码,我们注意到了两点:

  1. callapply改变了this的指向,指向到lulin

  2. sayHello函数执行了

这里默认大家都对this有一个基本的了解,知道什么时候this该指向谁,我们结合这两句话来分析这个通用函数:f.apply(o),我们直接看一本书对其中原理的解读,具体什么书,我也不知道,参数我们先不管,先了解其中的大致原理。

blob.png

注意红色框中的部分,f.call(o)其原理就是先通过 o.m = f 将 f作为o的某个临时属性m存储,然后执行m,执行完毕后将m属性删除。

知道了这个基本原来我们再来看看刚才jawil.sayHello.call(lulin, 24)执行的过程:

// 第一步lulin.fn = jawil.sayHello// 第二步lulin.fn()// 第三步delete lulin.fn

上面的说的是原理,可能你看的还有点抽象,下面我们用代码模拟实现apply一下。

实现aplly方法

模拟实现第一步

根据这个思路,我们可以尝试着去写第一版的 applyOne 函数:

// 第一版Function.prototype.applyOne = function(context) {    // 首先要获取调用call的函数,用this可以获取
    context.fn = this;
    context.fn();    delete context.fn;
}//简单写一个不带参数的demovar jawil = {
    name: "jawil",
    sayHello: function (age) {         console.log(this.name);
     }
};var  lulin = {
    name: "lulin",
};//看看结果:jawil.sayHello.applyOne(lulin)//lulin

正好可以打印lulin而不是之前的jawil了,哎,不容易啊!

声明:本站所有模板/文章除标明原创外,均来自网络转载,版权归原作者所有,如果有侵犯到您的权益,请联系本站删除,谢谢合作!
关于我们 - 联系方式 - 版权声明 - 招聘信息 - 邮箱:admin#webkfz.com
Copyright © 2017 webkfz.com Inc. All Rights Reserved. WEB开发者 版权所有