视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Javascript中有关this关键字的用法详解
2020-11-27 20:14:39 责编:小采
文档


this是Javascript中一个非常容易理解错,进而用错的特性。所以下面这篇文章主要给大家介绍了关于Javascript中this关键字指向问题的相关资料,文中通过测试的题目考验大家对this的熟悉程度,需要的朋友可以参考借鉴,下面来一起看看吧。

前言

Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象。Javascript可以通过一定的设计模式来实现面向对象的编程,其中this “指针”就是实现面向对象的一个很重要的特性。本文将给大家详细介绍关于Javascript中this关键字指向的相关内容,让我们先做一个小测试,如果全部答对了,恭喜你不用往下看了。

测试题目

第一题

<script>
 var str = 'zhangsan';

 function demo() {
 var str = 'lisi';
 alert(this.str);
 }
 window.demo(); // ??

 var obj = {
 str: "wangwu",
 say: function() {
 alert(this.str);
 }
 }
 obj.say(); // ??

 var fun = obj.say;
 window.fun(); // ??
</script>

第二题

<script>
 var username = 'zhangsan';

 (function() {
 var username = 'lisi';
 alert(this.username); // ??
 })()

 function demo() {
 var username = 'wangwu';

 function test() {
 alert(this.username);
 }

 test(); // ??
 }
 demo();
</script>

第三题

<script>
 function Person() {
 this.username = 'zhangsan';
 this.say = function() {
 alert('我叫' + this.username);
 }
 }

 var p = new Person();
 p.say(); // ??

 var p1 = new Person();
 p1.say(); // ??
</script>

第四题

<script>
 var username = 'zhangsan';

 function demo() {
 alert(this.username)
 }

 var obj1 = {
 username: "lisi"
 };
 var obj2 = {
 username: "wangwu"
 };

 demo(); // ??
 demo(obj1); // ??
 demo(obj2); // ??
 demo.call(obj1); // ?? 
 demo.apply(obj2); // ??
</script>

答案

  • 第一题:zhangsan wangwu zhangsan

  • 第二题:zhangsan zhangsan

  • 第三题:我叫zhangsan 我叫zhangsan

  • 第四题:zhangsan zhangsan zhangsan lisi wangwu

  • (往下看,下面有详细解析哦)

    this

  • 指向调用函数的对象

  • 无对象调用函数/匿名函数自调用(this指向window)

  • 通过new产生的对象

  • apply/call调用

  • 一、指向调用函数的对象

    <script>
     // this:指向调用函数的对象
     var str = 'zhangsan';
    
     function demo() {
     var str = 'lisi';
    
     //this->window
     console.log(this);
     alert(this.str);
     }
     window.demo(); // zhangsan
    
     var obj = {
     str: "wangwu",
     say: function() {
     // this->obj
     alert(this.str);
     }
     }
     obj.say(); // wangwu
    
     var fun = obj.say;
     window.fun(); // zhangsan
    </script>
  • 全局函数(demo)属于window对象的方法,window调用demo所以this就指向了window

  • obj调用say方法,this就指向了obj

  • fun()是全局函数,而声明的fun接收的是obj里面单纯的一个函数,并没有调用(obj.say()才是调用了函数),此时的fun就是一个函数(function(){alert(this.str);}),那么当fun()调用函数的时候,this指向的就是window

  • 是谁调用的函数,那么this就指向谁

  • 二、无对象调用函数/匿名函数自调用->this指向window

    <script>
     // 2.匿名函数自执行|匿名函数|无主函数 this->window
     var username = 'zhangsan';
    
     // 匿名函数自执行 this->window
     (function() {
     var username = 'lisi';
     console.log(this); // window
     alert(this.username); // zhangsan
     })()
    
     function demo() {
     var username = 'wangwu';
    
     // 无主函数 this->window
     function test() {
     // this->window
     alert(this.username);
     }
    
     test(); // zhangsan
     }
     demo();
    </script>
  • 因为匿名函数没有名字,所以就挂给window了

  • test(),谁调用test那么就指向谁。当然实验过,它不是window调用的,也不是demo调用的,没有人管它,那么它就指向window。它就相当于一个没有主人调用它,无主函数。

  • 三、通过new产生的对象

    <script>
     // 3.通过new的对象:this指向产生的对象
     // 函数
     function Person() {
     // 属性
     this.username = 'zhangsan';
     // 方法
     this.say = function() {
     // this->p
     console.log(this); // Person对象
     alert('我叫' + this.username);
     }
     }
    
     // 实例化出一个对象:p就具有了username属性和say方法
     var p = new Person();
     console.log(p); // Person对象
     console.log(p.username); // zhangsan
     p.say(); // 我叫zhangsan
    
     // this->p1
     var p1 = new Person();
     p1.say(); // Person对象 我叫zhangsan
    </script>
  • 当我们的函数Person里面运用了this去写属性和方法这种格式,那么就要通过new来让属性和方法变得有价值,通过new去运用函数里面的属性和方法

  • 四、apply/call调用

    首先我们来了解下apply()/call()是个什么东西呢?

    apply()/call():最终是调用function,只不过内部的this指向了thisObj

    注意:

    1. 调用function函数,但是函数内的this指向thisObj(更改对象内部指针)

    2. 如果thisObj没有传参,则默认为全局对象

    3. call()/apply()联系与区别

    联系:功能一样,第一个参数都是thisObj

    区别:传递的参数如果比较多

    call()的实参就是一一列出

    apply()的实参是全部放置在第二个数组参数中

    一个理解apply()/call()的实例:

    <script>
     // apply()/call()
     function demo() {
     console.log(123);
     }
    
     // 调用函数的时候,demo.call()/demo.apply()最终调用的还是demo()
     demo(); // 123
     demo.call(); //123
     demo.apply(); // 123
    </script>
    
    <script>
     // call()/apply()的区别:
     // call()参数单独再call中罗列
     // apply()的参数通过数组表示
     function demo(m, n, a, b) {
     alert(m + n + a + b);
     }
     demo(1, 5, 3, 4); // 13
     demo.call(null, 1, 5, 3, 4); // 13
     demo.apply(null, [1, 5, 3, 4]); // 13
    </script>

    this的第四个用法实例

    <script>
     // this的第四个用法:call(obj)/apply(obj):强制性的将this指向了obj
     var username = 'zhangsan';
    
     function demo() {
     alert(this.username)
     }
    
     var obj1 = {
     username: "lisi"
     };
     var obj2 = {
     username: "wangwu"
     };
    
     // call()/apply():打劫式的改变了this的指向
     demo(); // zhangsan
     demo(obj1); //zhangsan
     demo(obj2); //zhangsan
     demo.call(obj1); // lisi 
     demo.apply(obj2); // wangwu
    </script>
  • 如果直接调用demo里面写的不管是obj1还是obj2,那么demo还是属于window调用的。

  • 不管你用call还是apply最终调用的都是demo函数,但它们会强制的this指向了obj1/obj2,强制的指向了它们的第一个参数对象。

  • 下载本文
    显示全文
    专题