this是js里面很常用的关键字,而灵活的js也赋予了这个关键字无穷的生命力,相信你也有被它糊弄的时候,我总结了一个6字原则,大部分场合都能清醒分辨this到底指向who,跟大家分享一下,欢迎指正。

谁调用指向谁!

首先介绍一个大boss: window, 他是一个隐形大侠,没有确定的调用者的时候,肯定是它出手, 也就是说,如果一个对象没有显性的调用者时,this指向的就是window。

先看下面的例子:

  1. var x = 10;
  2. function test(){
  3. console.log("--- test this.x---");
  4. console.log(this.x);
  5. }
  6. var fruit = {
  7. x: 20,
  8. apple: function(){
  9. console.log("--- apple this.x---");
  10. console.log(this.x);
  11. }
  12. };
  13.  
  14. fruit.banana = function(){
  15. var y = 20;
  16. this.z = 20;
  17. function pear(){
  18. console.log("--- pear this.x---");
  19. console.log(this.x);
  20. }
  21. console.log("--- banana y---");
  22. console.log(y);
  23. console.log("--- banana this.y---");
  24. console.log(this.y);
  25. console.log("--- banana this.z---");
  26. console.log(this.z);
  27. pear();
  28. }
  29.  
  30. var myfruit = {
  31. x: 30
  32. }
  33. myfruit.mylove = fruit.apple;
  34.  
  35. test();
  36. fruit.apple();
  37. fruit.banana();
  38. test.call(fruit)
  39. myfruit.mylove();

example 1

运行结果分析:

  1. --- test this.x---
  2. 10 // this: window
  3. --- apple this.x---
  4. 20 // this: fruit
  5. --- banana y---
  6. 20
  7. --- banana this.y---
  8. undefined // this: fruit, we have not assign y to fruit.
  9. --- banana this.z---
  10. 20 // this: fruit
  11. --- pear this.x---
  12. 10 // this: window
  13. --- test this.x---
  14. 20 // this: fruit, it is fruit to call test.
  15. --- apple this.x---
  16. 30 // this: myfruit

从上述结果可以看到:

test();
// test()的调用者为隐形boss, this指向window。
fruit.apple();
// apple()的调用者为fruit, this指向fruit。
fruit.banana();
// banana()的调用者为fruit, this 指向fruit。
// 而banana()里面的pear(), 没有显性的调用者,尽管pear()在banana()定义,但是pear()为隐形boss调用,this指向的是window。
test.call(fruit)
// test()在window层面定义,然而实际调用者为fruit,所以this指向fruit。
myfruit.mylove();
// mylove()直接采用了apple()的定义,实际调用者为myfruit,并非fruit,所以this指向myfruit。

综上所述,6字原则可以非常完美的指认this是谁。 这种简单粗暴的方法屡试不爽。谁调用指向谁!!

温馨提示

在回调函数中使用this, 请谨慎谨慎谨慎。先上example:

  1. var x = 10;
  2. var fruit = {
  3. x: 20
  4. };
  5.  
  6. fruit.slice = function(callback){
  7. console.log("--- slice ---");
  8. console.log(this.x);
  9. console.log("--- callback begin---");
  10. callback();
  11. }
  12.  
  13. fruit.slice(function(){
  14. console.log("--- callback output---");
  15. console.log(this.x);
  16.  
  17. });

example 2

输出结果如下:

  1. --- slice ---
  2. 20
  3. --- callback begin---
  4. --- callback output---
  5. 10

回调函数里边的this竟然指向window!!!

我也被这个坑得不轻,回调函数里边的this并非指向宿主函数(调用回调函数的函数)的调用者,6字原则在这里还是非常灵光的,callback()调用时有显性调用者吗?没有!!!!因此,this指向是隐形boss window啦。

当然,例子中希望回调函数指向fruit也不难,call可以帮你忙,请看例子。

  1. var x = 10;
  2. var fruit = {
  3. x: 20
  4. };
  5. fruit.slice = function(callback){
  6. console.log("--- slice ---");
  7. console.log(this.x);
  8. console.log("--- callback begin---");
  9. callback.call(this);
  10. }
  11.  
  12. fruit.slice(function(){
  13. console.log("--- callback output---");
  14. console.log(this.x);
  15.  
  16. });

example 3

妥妥输出:

--- slice ---
20
--- callback begin---
--- callback output---
20

再强调一遍,6字原则在确定js关键字this是谁的问题上屡试不爽, 谁调用指向谁!言下之意,没有调用者就是隐形boss window

细心的看官也许会问, 第一个例子中的pear(), 既然里边的this指向window, 为什么不能在全局域中使用window.pear() or pear()呢?

Good question!

把这个问题用代码还原其实是这样:

  1. var fruit = {};
  2. fruit.banana = function(){
  3. function pear(){}
  4. }
  5.  
  6. // 这样调用会出错咯
  7. pear();
  8. // 这样调用也不行
  9. window.pear();

这两种方式调用都有exception,因为pear()只能在banana里面assign给banana的变量,或者在banana内部调用。

这样调用是对的;

  1. var fruit = {};
  2. fruit.banana = function(){
  3. this.callPear = pear; // assign 给callPear
  4. function pear(){ console.log("I am pear!");}
  5.    pear(); // 内部调用
  6. }
  7.  
  8. var instant = new fruit.banana();
  9. instant.callPear();

这涉及另外一个话题,作用域,scope!下次再跟大家详细分享scope。

五分钟看懂js关键字this的更多相关文章

  1. 五分钟看懂抓包神技:DPDK

    我是一个网络监控软件,我被开发出来的使命就是监控网络中进进出出的所有通信流量. 一直以来,我的工作都非常的出色,但是随着我监控的网络越来越庞大,网络中的通信流量也变得越来越多,我开始有些忙不过来了,逐 ...

  2. 五分钟看懂Celery定时任务

    Django下使用Celery 使用场景: 1, Web应用. 当用户触发的一个操作需要很长时间才能执行完成,那么就可以把它当做一个任务去交给Celery去异步执行, 执行完成之后再返回给用户,这短时 ...

  3. [转]五分钟看懂UML类图与类的关系详解

    在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...

  4. 五分钟看懂UML类图与类的关系详解

    在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...

  5. 一篇文章看懂JS闭包,都要2020年了,你怎么能还不懂闭包?

     壹 ❀ 引 我觉得每一位JavaScript工作者都无法避免与闭包打交道,就算在实际开发中不使用但面试中被问及也是常态了.就我而言对于闭包的理解仅止步于一些概念,看到相关代码我知道这是个闭包,但闭包 ...

  6. [转帖]10分钟看懂Docker和K8S

    10分钟看懂Docker和K8S https://zhuanlan.zhihu.com/p/53260098 2010年,几个搞IT的年轻人,在美国旧金山成立了一家名叫“dotCloud”的公司. 这 ...

  7. 十分钟看懂AES加密

    十分钟看懂AES加密算法 今天看了Moserware的<A Stick Figure Guide to the Advanced Encryption Standard(AES)>收获了不 ...

  8. 五分钟搞懂POM设计模式

    转载请注明出处️ 作者:IT小学生蔡坨坨 原文链接:五分钟搞懂POM设计模式 大家好,我是IT小学生蔡坨坨. 今天,我们来聊聊Web UI自动化测试中的POM设计模式. 为什么要用POM设计模式 前期 ...

  9. 五分钟读懂UML类图

    平时阅读一些远吗分析类文章或是设计应用架构时没少与UML类图打交道.实际上,UML类图中最常用到的元素五分钟就能掌握,下面赶紧来一起认识一下它吧: 一.类的属性的表示方式 在UML类图中,类使用包含类 ...

随机推荐

  1. leetcode 栈 括号匹配

    https://oj.leetcode.com/problems/valid-parentheses/ 遇到左括号入栈,遇到右括号出栈找匹配,为空或不匹配为空, public class Soluti ...

  2. 南京Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. Traffic Lights - SGU 103(最短路)

    题目大意:有一个城市的路线图,有N个交叉点,每两个交叉点之间只有一条路,现在想从交点u去交点v,不过这个路的交通比较特别,每个路都有一个交通灯,灯有两种颜色,蓝色和紫色,例如一条路线在交点s,t之间, ...

  4. hdoj 1686 Oulipo【求一个字符串在另一个字符串中出现次数】

    Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  5. runtime/KVO等面试题

    整理中... 1.KVO内部实现原则 回答:1>KVO是基于runtime机制实现的 2>当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中 ...

  6. 公司开发的APP,如何生成一个二维码,供客户下载使用

    1.其实和简单,因为一般的用户使用扫一扫,大多数都是用微信自带的扫一扫工具 而,微信打开的二维码页面,会自动屏蔽apk文件,所以显然把apk的url生成一个二维码,让用户扫一扫就能直接下载,这样是行不 ...

  7. 关于平移的 scrollTo和scrollBy的区别

    这几天在项目中要求一部分布局实现整体偏移的效果 在网上查了下我使用来ScrollBy(x,y)方法 他的意思是将view实现整体偏移 而ScollTo(x,y)则是将原点偏移到相应指定的位置即   移 ...

  8. 一个表的两个列连接另外一个表的一个列SQL语句怎么写

    f619424517 | 浏览 2207 次 推荐于2016-09-09 11:38:18   最佳答案   select a.flightid,a.flightname,b.cityname,c.c ...

  9. android的tabhost+RadioGroup+PopupWindow

    根据网上的代码稍作修改了下,放着记录学习. 效果图如下: 主代码如下: package com.andyidea.tabdemo; import android.app.TabActivity; im ...

  10. thinkphp 统计某个字段不重复数 总数

    $this->batch->count('DISTINCT intobatch');