美文网首页学习
关于js中this指向的那些事

关于js中this指向的那些事

作者: 周周很可爱 | 来源:发表于2019-10-30 21:03 被阅读0次

this是JS中的关键字,this的指向中函数定义时确定不了,只有 函数指向的时候才能确定this到底指向谁,this的最终指向的是那个调用他的对象
牢记以下三点

  1. this指向的,只可能是对象!
    2.this指向谁,不取决于this写在哪!而是取决于函数在哪里进行调用。
    3.this指向的对象,称之为函数的上下文context,也叫函数的调用者。

下面我用几个例子解释一下this
例子1:

  function fn(){
    var aa= "88";
    console.log(this.aa); //undefined
    console.log(this); //Window
 }
fn(); 
我们上面说this只有在函数执行的时候,才能去判断它最终指向的调用它的对象,函数是由window对象调用的,所以自然指向window,然而在window的属性中,没有aa这个变量,所以结果为undefined

 function fn(){
    var aa= "88";
    console.log(this.aa); //undefined
    console.log(this); //Window
 }
  window.fn();//window可以省略 等同于上面的代码

例子2:

    var obj = {
    name:"张三",
    who:function(){
        console.log(this.name);  //张三
    }
}
  obj.who();

函数在对象obj里面,调用函数时,是通过obj.who()调用的,所以这里的this指向obj,而obj里面是有一个name属性值的,所以结果为张三。

结合这两个例子,我们应该了解了this指向调用它的对象,但是对this的了解还不够深入,下面我再写几个例子补充一下
例子3:

 var name ="李二" ;
    var person = {
        name:"李三",
        say:function(){
            console.log(this.name);  //李三
    }
}
window.person.say();

  从这个例子可以看出,如果按照上面的推论的话,这里的this最终应该指向window,结果为李二才对。接着看下面这个例子

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

   如果根据上面的推断的话,这里的this应该指向obj才对,this.a结果应该为10才对。这样看来,可能你会觉得开头对于this指向的认知是错误的。其实并不是,只是不够准确而已。以下三条补充

如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window。
如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
如果一个函数中有this,这个函数中被多个对象包含,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

下面再看几个例子
例子4:

 var obj = {
a: 1,
b: {
    
    fn: function() {
        console.log(this.a) // undefined
    } 
       }
  }

obj.b.fn()

 输入的值是undefined,也就是说,这个时候this指向的是b的作用域,而b中没有定义a,所以是undefined

  var obj = {
    a: 1,
    b: {
    a: 2,
    fn: function() {
        console.log(this) // Window
        console.log(this.a) // undefined
    } 
}
 }

 var x = obj.b.fn
 x()

  谁调用,指向谁,这一句var x = obj.b.fn只是进行了赋值,把 fn赋值给了全局变量 x ,然而最终的调用时机是在 window作用域调用的函数 x(), 所以 this的指向是window对象

那我们如何改变 this 的指向呢?
通过 call, apply, bind 改变 this 的指向
例子5:

 var name = "小猫";
 var food = "鱼"
 var obj = {
name:this.name,
food:this.food,
state: function(name, food){
    console.log(`${this.name} 最喜欢的食物是${this.food}`)
   }
}

var skills = {
  name: '狗',
food: "骨头",
 }
obj.state() //小猫 最喜欢的食物是鱼
obj.state.call(skills)//狗 最喜欢的食物是骨头 
  obj.state.apply(skills) //狗 最喜欢的食物是骨头
obj.state.bind(skills)()//狗 最喜欢的食物是骨头

从上面看出来, call, apply, bind把this的指向改变为call, apply, bind所传入的第一个参数, 除此之外,他们是没有什么区别的,看看下面的例子

var name= "兔子"
 var food = "胡萝卜"
 var obj = {
 food:this.food,
name:this.name,
state: function(name, ow){
    console.log(`${this.name} 爱吃 ${this.food},但是${name}爱吃${ow}`)
}

 }

   var skills = {
 name: "熊二" ,
  food: '蜂蜜'
}
obj.state("羊","草") //兔子 爱吃 胡萝卜,但是羊爱吃草
obj.state.call(skills,"大灰狼","小绵羊") //熊二 爱吃 蜂蜜,但是大灰狼爱吃小绵羊
obj.state.apply(skills,["狐狸","葡萄"]) // 熊二 爱吃 蜂蜜,但是狐狸爱吃葡萄
obj.state.bind(skills,"猫","鱼")() //熊二 爱吃 蜂蜜,但是猫爱吃鱼

apply第二个参数接受的是一个数组, call 直接按参数排列就可以了,而 bind 跟call相似,只不过后面多了个 ()
上面是本人对于this指向的一些理解,如有错误或不足,望指出。

相关文章

网友评论

    本文标题:关于js中this指向的那些事

    本文链接:https://www.haomeiwen.com/subject/mmravctx.html