为何常常栽在call,apply,bind这些函数
1. call、apply、bind作用于函数上
2. call
<script type="text/javascript"> var Dog = function () { this.name = "旺星人"; this.shout = function () { alert(this.name); } }; var Cat = function () { this.name = "喵星人"; }; var dog = new Dog(); var cat = new Cat(); dog.shout.call(cat); //dog.shout中的this对象,将指向cat对象。 dog.shout(); //this还是指向dog </script>
3. apply
<script type="text/javascript"> var xh = { name: "小红", job: "JS工程师" }; var xm = { name: "小明", job: "资深前端开发工程师" }; var jx = { name: "杰西", job: "前端开发总监" }; //杰西,男,今年24岁,在前端开发网担任前端开发总监一职 function myjob(gender, age, company) { alert(this.name + "," + gender + ",今年" + age + "岁,在" + company + "担任" + this.job + "一职"); } myjob.call(xh, "女", 22, "腾讯"); myjob.call(xm, "男", 23, "谷歌"); myjob.call(jx, "男", 24, "前端开发网"); myjob.apply(xh, ["女", 22, "腾讯"]); myjob.apply(xm, ["男", 23, "谷歌"]); myjob.apply(jx, ["男", 24, "前端开发网"]);</script>
总结:
在call传入参数的时候,需要与函数所接受的参数一一对应;
在apply传入参数的时候,则以数组的方式传入,数组中的元素需要与函数所接受的参数一一对应;
call、apply都是属于立即调用
3.bind
MDN的解释是:bind()方法会创建一个(新函数),称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
// 1.常用this赋值写法<script type="text/javascript"> var foo = { bar: 1, eventBind: function () { var _this = this; $('.someClass').on('click', function (event) { /* Act on the event */ console.log(_this.bar); //1 }); } }</script>// 2.bind()改变this指向<script type="text/javascript"> var foo = { bar: 1, eventBind: function () { $('.someClass').on('click', function (event) { /* Act on the event */ console.log(this.bar); //1 }.bind(this)); } }</script>
直接使用对象属性
<script type="text/javascript"> var jx = { name: "杰西", gender: "男", age: 24, company: "前端开发网(W3Cfuns.com)", job: "前端开发总监", say: function () { alert(this.name + "," + this.gender + ",今年" + this.age + "岁,在" + this.company + "担任" + this.job + "一职"); } }; jx.say(); var xm = jx.say.bind({ name: "小明", gender: "男", age: 23, company: "谷歌 Google", job: "资深前端开发工程师" }); xm(); //注意:JavaScript1.8.5版本中,原生实现bind方法,目前IE9+,FF4,Chrome7+,opera</script>
重复使用bind会有什么效果
<script type="text/javascript"> var bar = function () { console.log(this.x); } var foo = { x: 3 } var sed = { x: 4 } var func = bar.bind(foo).bind(sed); func(); //? var fiv = { x: 5 } var func = bar.bind(foo).bind(sed).bind(fiv); func(); //?</script>
答案是,两次都仍将输出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。
apply、call、bind比较
<script type="text/javascript"> 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</script>
三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。
也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。
再总结一下:
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
作者:饥人谷_米弥轮
链接:https://www.jianshu.com/p/ac41b4bca8b8
共同学习,写下你的评论
评论加载中...
作者其他优质文章