zoukankan      html  css  js  c++  java
  • this的用法

    在编写前端代码时会频繁的用到‘this’,所以今天就静下心来好好研究了一番,跟大家一起分享!

    首先,先清楚一点,this的用武之地:

    1、一般函数方法中

    2、对象函数调用

    3、构造函数调用

    4、call、apply、bind调用


    先看一般函数方法中的情况:

    var name = "中国";

    function getName(){

    console.log(this.name)

    }

    getName();——结果为‘中国’;

    解释:函数的赋值和定义都是在全局作用域内完成的(这里需要提前了解全局作用域是啥情况哦),而一般我们认为在浏览器环境中全局对象就是window。所以在执行getName函数时,this就是指向的window。而name又是全局变量,所以结果就为“中国”。


    var name = "中国";

    function getName(){

    var name = "祖国”

    console.log(this.name)

    function getName2(){

    console.log(this.name)

    }

    getName2()

    }

    getName()——结果为: 中国  中国。

    解释:第一个打印可以上面的情况理解,为啥第二条打印结果也是“中国”呢?————因为getName2()也是独立调用的,调用对应是浏览器的全局对象window,所以this结果也是指向全局变量;

    那那。。。怎样才能打印出我们想要的“祖国”呢?接下来继续看。。。。

    (接下来这个是对象调用情况下this的指向)

    var name = "中国”,

    var nameObj = {

      name:"祖国”,

      getName:funtion(){

       console.log(this.name)

      }

    }

    nameObj.getName(); ———结果为:祖国。

    解释:为啥这次就能打印出想要的结果呢?——与上面对比发现,后者的getName方法前面多了一个nameObj对象,前面加了对象,this的指向就发生了变化,就不再指向window了,而是被对象nameObj给拐了,而nameObj的作用域内name为“祖国”,所以打印出的结果就是对象中定义的name值。

    那再加深一点看看。。。

    var name = "中国”,

    var nameObj = {

      name:"祖国”,

      newName:{

         name:"母亲",

         getNewName:function(){

          console.log(this.name)     

         }

      }

    }

    nameObj.newName.getNewName()——结果为 :母亲。

    综合上面四个案例,可以得出结论如下:

    一、如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,但是在严格版中不是window。(简要概括就是函数独立调用都指向window)

    二、如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。(简要概括就是函数作为一个对象被调用,那么this就指向这个对象)

    三、如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。(简要概括就是函数作为多层对象被调用,那么this就指向最近上一级对象)

    另外,再说明一点:

    在对象调用时使用声明函数和函数表达式的结果是不一样的;

    为啥这么说呢?请看下面讲解:

    还是结合上面第四个案例来看,我把函数声明形式改成函数表示式再执行:

    var name = "中国”,

    var nameObj = {

      name:"祖国”,

      newName:{

         name:"母亲",

         getNewName:function(){

          console.log(this.name)     

         }

      }

    }

    var nameNew = nameObj.newName.getNewName

     nameNew()——结果为 :中国。

    这个时候是不是要怀疑人生了,this就是这么跳,让你难以驾驭。。。我也纳闷了好久。。。为啥呢为啥呢为啥呢?

    解释一下吧:前面不是说过声明函数的声明和赋值都是在全局作用域内完成的嘛,匿名函数也一样,所以匿名函数的指向也是指向window的。而函数表达式是将函数传给一个变量,如果后面没有加括号那么就只是传递了一个函数(这里是匿名函数),而不是执行结果。即就是只将匿名函数的内存地址传给了变量,而这个匿名函数是指向window的,所以结果就是全局变量name的值。

    感觉真的快要被this搞晕了。。。。

    其实this都是指向的实例化对象,而全局作用域中的实例化对象都是window,所以那么多this都指向window其实都是因为只做了一次实例化,所以想改变this的指向就进行实例化。。

    怎样实例化呢?一个关键字new就能解决;

    那么接下来就看一看,this在构造函数中的使用情况:

    function Person() {
    this.name = '小米';
    this.age = '5';
    this.getPerson = function () {
    console.log(this.name + '今年' +this.age + '岁')
    }
    }
    var p1 = new Person();
    p1.getPerson();——————————结果为:小米今年5岁
    由此可见上面构造函数中的this指向的是对象p1。
    解释:p1是创建了Person的实例对象,就相当于复制了一份Person到p1对象里面,此时是创建了一个新的对象,后面对象调用getPerson函数,根据上面的总结this指向上一级调用对象,所以this就指向了
    person的复制版本中,因为Person中给name和age都赋值了,所以能够获取到结果。

    再加一点说明:javascript中构造函数是不需要有返回值的,可以认为构造函数和普通函数之间的区别就是:构造函数没有 return 语句,普通函数可以有 return 语句;


    最后来看看call、apply和bind中的调用:
     var x =0;
    function test() {
    console.log(this.x);
    };
    var ceshi = {
    x:99
    }
    test.apply(); ——————————结果为0;
    test.apply(ceshi); ——————————结果为99;
    解释一下:call、apply、bind三者的第一个参数都是this要指向的对象;而第一种情况apply()里面对象是空就默认指向window,所以结果为0,
    如果加了对象ceshi那this就指向了ceshi对象,所以结果为99;


    好了,this的用法就先总结到这吧,如果我的解释不够清晰,推荐两个链接再学习下:https://blog.csdn.net/u012244479/article/details/79579984和https://www.cnblogs.com/sspeng/p/6633204.html

    有什么不对的地方欢迎大家批评指正~~~~~



     
  • 相关阅读:
    thinkphp empty标签
    thinkphp present标签
    if标签
    thinkphp 范围标签
    thinkphp 比较标签
    thinkphp switch标签
    thinkphp for标签
    thinkphp foreach标签
    QueryList 来做采集
    thinkphp volist标签
  • 原文地址:https://www.cnblogs.com/jennydtt/p/9829087.html
Copyright © 2011-2022 走看看