js的call,apply,bind的使用与区别
在原生js中会有三个很常见的函数,call,apply,bind
他们的作用就是改变当前函数的this指针,
但是细微来说他们还是有不同的。
1)call,apply都是执行某一函数,发现this有变得时候才使用的(进行时)
2)bind是在函数进行调用之前,就强行给变了this的指向(进行前),它的效果是返回一个函数(只是给变了this指向)
说的很多了,不说了
demo :
function Foo(name){
this.name=name;
} Foo.prototype.getName=function(){
return this.name;
} function Bar(name,label){
Foo.call(this,name);
this.label=label;
} Bar.prototype.getMylabel=function(){
return this.label;
} var fo=new Foo('一灯');
console.log(fo.getName()); //一灯 var ba=new Bar("是你的?","大家的");
console.log( ba.getMylabel()); //大家的 console.log(ba);//bar{label:大家的,name:是你的?}
明白人都会有个问题,这个ba怎么将name值赋值成功的,因为他没有Foo方法呀?
这就是call的厉害了。慢慢体会其中奥秒,
一个问题:怎么把call换成apply???
只需要这样: Foo.call(this,name);要被改变成--->Foo.apply(this,[name]).....多说一句,applay与call的却别就是applay的参数是一个数组,
第二个问题:怎么换成bind呢????
已经说过bind的使用是函数进行前进行操作的,返回一个函数
var setName=Foo.bind(this);
setName(name);
当然也可以写成一句话:Foo.bind(this)(name);表面上来看,好像只是与call多了一个括号,但是含义确实不同,bind是先返回一个函数,然后执行函数,,,,,,
第三个问题:我要怎么输出我的ba中的name呢???
很简单呀:console.log(ba.getName());
嗯,错了,确实错了,ba没有getName()方法呀。
怎么办了,这里
方法不唯一.
第一种方法:
console.log(Foo.prototype.getName.call(ba));
或者 console.log(Foo.prototype.getName.bind(ba)());
console.log(Foo.prototype.getName.apply(ba));
第二种方法:
Bar.prototype=Object.create(Foo.prototype);
console.log(ba.getName());//是你的?
【Objecrt.create的作用就是将Foo.prototype与Bar.prototype相关联起来】
console.log(ba.getMylable());//error 出错了什么鬼???????
【忘记说了,Object.create()他会出创建一个新对象,这样Bar.prototype就会被替换了,这样就尴尬了,getMylabel()就丢了。。。。。。。】
聪明的孩纸说:那么就这样来:
Bar.prototype=Object.create(Foo.prototype);
Bar.prototype.getMylabel=function(){
return this.label;
}
一点毛病也没用,很好。
其实能更高雅点,当你翻开你的课本,你就会发现其实,Object.setPrototypeOf(Bar.prototype,Foo.Prototype)即可规避上面的尴尬现象了,
Object.setPrototypeOf(Bar.prototype,Foo.Prototype)会改变前者的一些东西,不会将他抛弃
到这里我已经没什么好说的,只想说,bind函数具有一定的兼容性问题
js的call,apply,bind的使用与区别的更多相关文章
- JS 的 call apply bind 方法
js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[, [,.argN]]]] ...
- JS中call,apply,bind方法的总结
why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user: "小马扎", fn: ...
- 学习前端的菜鸡对JS的call,apply,bind的通俗易懂理解
call,apply,bind 在JavaScript中,call.apply和bind是Function对象自带的三个方法,都是为了改变函数体内部 this 的指向. a ...
- js: this,call,apply,bind 总结
对js中的一些基本的很重要的概念做一些总结,对进一步学习js很重. 一.this JavaScript 中的 this 总是指向一个对象,而具体指向那个对象是在运行时基于函数的执行环境动态绑定的,而非 ...
- js 中call,apply,bind的区别
call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...
- 原生JS实现call,apply,bind函数
1. 前言 使用原生JS实现call和apply函数,充分了解其内部原理.call和apply都是为了解决改变this的指向.作用都相同,只是传参的方式不同.除了第一个参数外,call可以接受一个参数 ...
- js笔记——call,apply,bind使用笔记
call和apply obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1, arg2, ...]); 两者作用一致,都是把obj( ...
- JS之call/apply/bind
测试代码: var a = 1; var obj = { a = 2; } function test(a){ alert(a); alert(this.a); } 1.test(3); 结果:3,1 ...
- js 对call apply bind理解
请参考 http://www.cnblogs.com/xljzlw/p/3775162.html 1.call和apply的区别:参数类型不同var mtt = { name: "mtt&q ...
- js new call apply bind 的 原理
new new 做了什么事?1. 以 Object.protoype 为原型创建一个新对象 2. 以新对象为 this,执行函数的 [[call]] 3. 如果 [[call]] 的返回值是对象,那么 ...
随机推荐
- react系列从零开始-react介绍
react算是目前最火的js MVC框架了,写一个react系列的博客,顺便回忆一下react的基础知识,新入门前端的小白,可以持续关注,我会从零开始教大家用react开发一个完整的项目,也会涉及到w ...
- MySQL--当mysqldump --single-transaction遇到alter table(2)
在上篇<MySQL--当mysqldump --single-transaction遇到alter table>中测试发现,在MySQL 5.6版本中,如果在mysqldump期间修改表, ...
- 关于Latex中插入Visio图片文字不显示的问题
经过探索,将Visio保存为pdf格式是最完美的解决方式,因为pdf文件保存了所有格式和字体信息. Visio输出pdf时要使其符合PDF/A标准.如果包含Visio的多余信息,就会在一些低版本Lat ...
- Vijos 1002 过河 状态压缩DP
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...
- javascript精度问题与调整
一个经典的问题: 0.1+0.2==0.3 答案是:false 因为:0.1+0.2=0.30000000000000004 第一次看到这个结果就是无比惊讶,下巴碰到地上,得深入了解下问题出在哪里,该 ...
- ps命令学习笔记
最近在看linux优化大师这本书,第2章祥细讲解了分析系统用的工具,这里把一些内容整理出来,以便加深印像. 当进行系统分析时,ps命令显示有关选择的活跃进程的信息.ps命令提供当前已存在的进程列表,和 ...
- js中嵌入jsp(html)代码的双引号转换问题--事件没反应
下面是一段今天遇到问题的代码,select中写了onchange事件 ,在没有加转义的情况下,F12解析的代码是错乱的,双引号与内容中写的不一致,还会有空格出现,经过一段时间的摸索,发现在出错的地方加 ...
- CentOS 6.9 升级MySQL 5.6.36到5.7.18
CentOS 6.9 升级MySQL 5.6.36到5.7.18 MySQL 5.6.36 安装过程:http://www.cnblogs.com/imweihao/p/7156754.html 升级 ...
- MySQL触发器更新和插入操作
一.触发器概念 触发器(trigger):监视某种情况,并触发某种操作,它是提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动 ...
- 关于阻止PROE联网的一些想法!
前言:商业上使用盗版proe会被官方警告,官方是通过proe软件联网来获取你的ip地址,那他是怎么知道你是商业用途而不是个人(一般不会对个人的盗版行为进行警告)?这不难,应该是通过检测同一ip下有多台 ...