21、JS中的this详解

this基础理解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
   
      解析器每次调用函数时,都会向函数内部传递进一个隐含的参数
        这个隐含的参数就是this,this指向的一个对象
        该对象为函数执行的上下文对象
        根据函数的调用方式的不同,this会指向不同的对象
        跟创建方式没有关系。
          1.以函数的形式调用,this为window
          2.以方法的形式调用时,this 为调用该方法的对象
        

    function fun(){
        console.log(this);
        console.log(this.name)
    }
    // 此处输出的window
   fun();
   
   var obj={
       name:'swk',
       sayName:fun
   }
   // 此处输出的为object
   obj.sayName();
   
   var name = "全局的name属性"fun()// 此处输出  全局的name属性
    </script>

  
</head>
<body>
</body>

1、在方法中,this表示该方法所属的对象
如下所示:

var Person ={
    firstName:'John',
    lastName:'Doe',
    id:5566,
    fullName:function(){
        return this.firstName+""+this.lastName;
    }
}

在上述的队形方法中,this指向调用它所在的方法的对象,即this表示person对象。
2、单独使用this,this指向全局对象。在浏览器中,window就是全局对象

<script>
var x = this;
document.getElementById("demo").innerHTML = x;// 输出window
</script>

严格模式下,如果单独使用,this也是指向全局对象

<script>
"use strict";
var x = this;
document.getElementById("demo").innerHTML = x;// window
</script>

3、在函数中,this 表示全局对象。

<script>
// 输出window
document.getElementById("demo").innerHTML = myFunction();
function myFunction() {
  return this;
}
</script>

严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
<script>
"use strict";
// 输出undefined
document.getElementById("demo").innerHTML = myFunction();
function myFunction() {
  return this;
}
</script>

4、事件中的this指向了接受事件的HTML元素

如下,this指向了onclick事件
<button onclick="this.style.display='none'">点我后我就消失了</button>

5、 显示的函数绑定
在JavaScript中函数也是对象,对象则有方法,apply 和call就是函数对象的方法。这两个
方法允许函数切换执行的上下文环境(context),即this绑定的对象
如下所示:

var person1={
    fullName:function(){
        return this.firstName + ""+this.lastName;
    }
}
var person2 = {
    firstName:'John',
    lastName:'doe',
}
person1.fullName.call(person2);//返回John doe

上例中,当我们使用person2作为参数调用person1.fullName 方法时,this将指向person2,即便它是person1的方法。

this中深入理解

首先要声明一点:this的指向只有在函数执行时候才能确定,在定义时是不能确定的。实际上this的指向最终指向的是那个调用它的对象。
如下所示:
例子1:

function a(){
    var user = "追梦子";
    console.log(this.user); // undefined
    console.log(this);// Window
}
// 执行函数,相当于window对象调用函数,即window.a(),所以this->window
a();

例子2:

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

这里的this的指向是对象o,因为调用函数fn是通过o.fn()执行的,那自然指向就是对象o。这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。

上述两个例子说的并不准确,接下来要想彻底搞懂this必须看下面几个例子。

例子3:

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

这段代码和上面的那段代码几乎是一样的,但是这里的this为什么不是指向window,如果按照上面的理论,最终this指向的是调用它的对象。这里先说个而外话,window是js中的全局对象,我们创建的变量实际上是给window添加属性,所以这里可以用window点o对象。
  这里先不解释为什么上面的那段代码this为什么没有指向window,我们再来看一段代码。

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

这里同样也是对象o点出来的,但是同样this并没有执行它,那你肯定会说我一开始说的那些不就都是错误的吗?其实也不是,只是一开始说的不准确,接下来我将补充一句话,我相信你就可以彻底的理解this的指向的问题。

情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window。这里需要说明的是在JS的严格把那种this指向的不是window.
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级对象
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级对象,例子3可以证明,接下来例子也可以证明

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

尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。
比较特殊的情况,例子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();

这里的this指向的是window,是不是有些蒙了?其实是因为你没有理解一句话,这句话同样至关重要。

this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn。

构造函数版this:

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

这里之所以对象a可以点出函数Fn里面的user,这是因为关键字可以改变this的指向,将这个this指向对象a,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

其它情况:

function fn(){
    this.user='追梦子'return {};
}
var a=new fn();
console.log(a.user);// undefined

function fn(){
    this.user='追梦子';
    return function(){};
}
var a=new fn();
console.log(a.user);// undefined

function fn(){
    this.user='追梦子'return 1}
var a= new fn();
console.log(a.user);// 追梦子

function fn(){
    this.user='追梦子'return undefined;
}

var a=new fn();
console.log(a.user);// 追梦子

上述例子说明,如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是执行函数的实例

还有一点,虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊

function fn(){
    this.user='追梦子'return null;
}
var a=new fn();
console.log(a.user)// 追梦子
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值