您的位置:首页 > 移动开发

理解JS中的this指向,call,apply,与bind

2020-05-23 15:58 281 查看

理解JS中的this指向

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

  1. 情况1: 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
  2. 情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
  3. 情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
    示例1
    .
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();

示例2
.

var o = {
user:"追梦子",
fn:function(){
console.log(this.user);  //追梦子
}
}
o.fn();

示例3
.

var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();

示例4
.

var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();//虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window

构造函数版this:
new关键字可以改变this的指向,将这个this指向对象a

function Fn(){
this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子

更新一个小问题当this碰到return时:如果返回值是一个对象(此处null作为非对象处理),那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

//返回对象,指向该对象
function fn()
{
this.user = '追梦子';
return {};
}
var a = new fn;
console.log(a.user); //undefined
//非对象,指向函数实例
function fn()
{
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子

call、apply、bind更改对象的内部指针,即改变对象的this指向的内容

call与apply:
对于apply和call两者在作用上是相同的,但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call**则作为call的参数传入(从第二个参数开始)。如 func.call(func1,var1,var2,var3)对应的apply写法为func.apply(func1,[var1,var2,var3])同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入。

function Obj(){this.value="对象!";}
var value="global 变量";
function Fun1(){alert(this.value);}

window.Fun1();   //global 变量
Fun1.call(window);  //global 变量
Fun1.call(new Obj());   //对象!

bind:
bind方法与call、apply最大的不同就是前者返回一个绑定上下文的函数,而后两者是直接执行了函数。用一句话总结bind的用法:该方法创建一个新函数,称为绑定函数,绑定函数会以创建它时传入bind方法的第一个参数作为this,传入bind方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
bind方法传递给调用函数的参数可以逐个列出,也可以写在数组中。

var a = {
user:"追梦子",
fn:function(e,d,f){
console.log(this.user); //追梦子
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: