JavaScript函数this指向问题详解
目录
一、 函数内 this 的指向 1、普通函数 2、构造函数 3、对象方法 4、事件绑定方法 5、定时器函数 6、立即执行函数 二、改变函数内部 this 指向 1、call 方法 2、apply 方法 3、bind 方法 三、call apply bind 总结 1、相同点 2、不同点 3、应用场景 总结一、 函数内 this 的指向
这些 this的指向,是当调用函数的时候确定的。 调用方式的不同决定了this 的指向不同,一般指向调用者。 现在我们来具体看看吧!
1、普通函数
function fn(){ console.log('普通函数的this:'+this); } fn()
打印结果为:
可知普通函数调用时this指向的是 window
2、构造函数
function Star(){ console.log('构造函数的this:'+this); } new Star()
打印结果为:
可知对象方法调用时this指向的是该方法的实例对象。
3、对象方法
var o = { print: function(){ console.log('对象方法的this:'+this); } } o.print()
打印结果为:
可知对象方法调用时this指向的是该方法所属对象。
4、事件绑定方法
当我们给某个按钮添加了一个绑定事件,他的this又是如何指向的呢?
例如现在有一个button按钮,现在我们给它添加一个点击事件,如下:
<body> <button>按钮</button> <script> var btn = document.querySelector('button'); btn.onclick = function(){ console.log('绑定事件的this:'+this); } </script> </body>
当我们点击按钮时,可以得到:
可知,绑定事件调用时this指向的是绑定事件对象。
5、定时器函数
写一个定时函数,让他在1s后调用该函数。
window.setTimeout(function(){ console.log('定时器的this:'+this); },1000)
打印结果为:
可知,定时器函数调用时this指向的是window。
6、立即执行函数
定义一个立即执行函数:
(function(){ console.log('立即执行函数的this:'+this); })();
打印结果为:
可知,立即执行函数调用时this指向的是window。
综上,我们可以总结为:
调用方式 this指向 普通函数调用 window 构造函数调用 实例对象,原型对象里面的方法也指向实例对象 对象方法调用 该方法所属对象 事件绑定方法 绑定事件对象 定时器函数 window 立即执行函数 window二、改变函数内部 this 指向
但是在函数中,this指向也不是一成不变的,我们可以通过一些方法来更改this指向,主要有以下几种方法。前面在总结原型对象中this的指向问题中,有提到过call方法和apply方法,这里就不重复了,直接举例。
1、call 方法
先定义一个对象和一个函数。
var o = { name:'xl' } function fn(){ console.log(this); }
此时的this在一个普通的函数里面,前面有提到过,普通函数的this指向windiw,现在如果想将this的指向o对象,我们应该:
fn.call(o)
打印的结果为:
this指向成功修改。
2、apply 方法
方法同上。
var o = { name:'xl' } function fn(){ console.log(this); } fn.apply(o);
打印结果为:
3、bind 方法
bind()方法不会调用函数。但是能改变函数内部this指向 。
语法:
fun.bind(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值arg1,arg2:传递的其他参数返回由指定的 this 值和初始化参数改造的原函数拷贝
因此当我们只是想改变this 指向,并且不想调用这个函数的时候,可以使用 bind。
如下(还是用上面的例子):
var o = { name:'xl' } function fn(){ console.log(this); } var f = fn.bind(o); f();
打印结果为:
这里需要注意的是:由于bind()方法不会调用函数,修改this指向后,返回的是一个新函数,所以我们可以将这个新函数赋给一个f,然后通过f来调用。
三、call apply bind 总结
1、相同点
都可以改变函数内部的this指向。
2、不同点
call
和 apply
会调用函数, 并且改变函数内部this指向。
-call
和 apply
传递的参数不一样, call 传递参数 aru1, aru2…形式 apply必须数组形式[arg]。
bind
不会调用函数, 可以改变函数内部this指向。
3、应用场景
call
经常做继承。
apply
经常跟数组有关系。比如借助于数学对象实现数组最大值最小值。
bind
不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向。
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!