ES5 call,apply,bind方法总结(包括理解this的指向问题)
栏目: JavaScript · 发布时间: 5年前
内容简介:call,apply,bind这三个方法在JavaScript中是用来改变函数调用的this指向。那么改变函数this指向有什么用呢?我们先来看一段代码调用a.fn方法后得到了harden,但在b方法中我想得到harden,为什么却是undefined呢?原因是方法在执行的时候才能确定this到底指向谁,实际上this指向的是在开始讲call,apply,bind方法前,一起来总结一下this的指向问题。
总结call,apply,bind方法的理解使用和区别。
call,apply,bind这三个方法在JavaScript中是用来改变函数调用的this指向。那么改变函数this指向有什么用呢?我们先来看一段代码
var a= { name:'harden', fn:function () { console.log(this.name); } } var b = a.fn; a.fn();//harden b();//undefined
调用a.fn方法后得到了harden,但在b方法中我想得到harden,为什么却是undefined呢?原因是方法在执行的时候才能确定this到底指向谁,实际上this指向的是 最终 调用函数的对象。这里当b执行时,实际是window调用了fn函数,那么fn中的this就指向window。
在开始讲call,apply,bind方法前,一起来总结一下this的指向问题。
理解JavaScript中的this指向问题。
总体来说this指向可以概括为一句话:this指向在函数的定义时是不确定的,只有函数执行时才能确定this到底指向谁,实际上this的 最终 指向的是那个调用它的对象。但是这个说法在函数被很多对象包裹的时候并不成立,请看下面例子。
简单来说就是:谁(哪个对象)调用的这个函数,那么这个函数中的this就指向这个对象。
例一
function a(){ var name= "harden"; console.log(this.name); //undefined console.log(this); //Window } a();
因为this最终指向调用他的对象,在上述代码中其实是widow触发的这个方法,那么this就指向window,window中并没有定义a,那么就打印出undefined。
例二:
var a = { name:'harden', fn:function() { console.log(this.name);//harden console.log(this);//指向a(可以自己跑一下) } } a.fn()
这里的this指向a,因为这里的fn函数是通过 a.fn()
执行的,那么this自然指向a。
说到这我就有疑问了,如果我用 window.a.fn()
执行函数,this不就指向window了吗?然后并不是这样的,请看下一个例子。补充一点:window是js的全局对象。
例三:
var a = { name:'harden', b:{ name:'james', fn:function() { console.log(this.name);//james console.log(this);//指向b } } } a.b.fn()
我们看到最终是a调用的方法,那为什么this会指向b呢?现在总结三句话,来完全理解this的指向问题:
情况一:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window(除去严格模式外)。
情况二:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
情况三:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子3可以证明。
-
构造函数中的this:
function Fn(){ this.name = "harden"; } var a = new Fn(); console.log(a.name); //harden
这里的a可以点出name,因为new关键字会改变this的指向。为什么new关键字会改变this呢,我自己有两种看法:
1.在new的过程中会创建一个实例对象,通过apply等方法 通过 Fn.apply({}) 使this指向这个空对象,最后把fn方法中的材料加工完后返回给a。
-
当this遇到return的时候:
function fn() { this.user = 'harden'; return {}; } var a = new fn; console.log(a.user); //undefined function fn() { this.user = 'harden'; return function(){}; } var a = new fn; console.log(a.user); //undefined function fn() { this.user = 'harden'; return 1; } var a = new fn; console.log(a.user); //harden function fn() { this.user = 'harden'; return undefined; } var a = new fn; console.log(a.user); //harden
总结一下:如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。还有一点就是返回null,null也是对象,但是因为他的特殊性,返回后this还是指向函数本身的实例。 理解JavaScript中的指向问题
理解完JavaScript中的指向问题,那么回到正题:
call,apply,bind方法总结
1.call
a = { name: 'harden' } function b () { console.log(this.name); } b.call(a);//harden b()//undefined
b.call(a)用字面意思来讲就是:把函数b添加到对象a的环境中,使函数中的this指向对象a。
call与apply不同的地方就是传参不同。
2.apply
a = { name: 'harden' } function b (data1,data2) { console.log(data1,data2); } b.call(a,'a1','a2');//a1 a2 b.apply(a,['a1','a2']);//a1 a2
3.bind
a = { name: 'harden' } function b () { console.log(this.name); } b.bind(a);//不会执行函数 var aaa = b.bind(a); aaa()//harden
bind不会立即调用函数,是把函数返回,bind通常用它来指定回调函数的this。
关于call, apply, bind方法的区别与内部实现以上所述就是小编给大家介绍的《ES5 call,apply,bind方法总结(包括理解this的指向问题)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
RabbitMQ实战
Alvaro Videla、Jason J. W. Williams / 汪佳南 / 电子工业出版社 / 2015-10 / 75.00元
本书对RabbitMQ做了全面、翔实的讲解,体现了两位专家的真知灼见。本书首先介绍了有关MQ的历史,然后从基本的消息通信原理讲起,带领读者一路探索RabbitMQ的消息通信世界。这当中不仅包含了针对单台RabbitMQ服务器和RabbitMQ集群的讲解,还教导读者如何使用各种工具来进行监控。 本书内容浅显易懂,文笔风趣幽默。书中包含了丰富的、可以运行的示例程序源代码,读者可以自行下载并运行,......一起来看看 《RabbitMQ实战》 这本书的介绍吧!