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

谁调用指向谁!

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

先看下面的例子:

var x = 10;
function test(){
console.log("--- test this.x---");
console.log(this.x);
}
var fruit = {
x: 20,
apple: function(){
console.log("--- apple this.x---");
console.log(this.x);
}
}; fruit.banana = function(){
var y = 20;
this.z = 20;
function pear(){
console.log("--- pear this.x---");
console.log(this.x);
}
console.log("--- banana y---");
console.log(y);
console.log("--- banana this.y---");
console.log(this.y);
console.log("--- banana this.z---");
console.log(this.z);
pear();
} var myfruit = {
x: 30
}
myfruit.mylove = fruit.apple; test();
fruit.apple();
fruit.banana();
test.call(fruit)
myfruit.mylove();

example 1

运行结果分析:

 --- test this.x---
10 // this: window
--- apple this.x---
20 // this: fruit
--- banana y---
20
--- banana this.y---
undefined // this: fruit, we have not assign y to fruit.
--- banana this.z---
20 // this: fruit
--- pear this.x---
10 // this: window
--- test this.x---
20 // this: fruit, it is fruit to call test.
--- apple this.x---
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:

var x = 10;
var fruit = {
x: 20
}; fruit.slice = function(callback){
console.log("--- slice ---");
console.log(this.x);
console.log("--- callback begin---");
callback();
} fruit.slice(function(){
console.log("--- callback output---");
console.log(this.x); });

example 2

输出结果如下:

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

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

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

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

var x = 10;
var fruit = {
x: 20
};
fruit.slice = function(callback){
console.log("--- slice ---");
console.log(this.x);
console.log("--- callback begin---");
callback.call(this);
} fruit.slice(function(){
console.log("--- callback output---");
console.log(this.x); });

example 3

妥妥输出:

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

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

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

Good question!

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

var fruit = {};
fruit.banana = function(){
function pear(){}
} // 这样调用会出错咯
pear();
// 这样调用也不行
window.pear();

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

这样调用是对的;

var fruit = {};
fruit.banana = function(){
this.callPear = pear; // assign 给callPear
function pear(){ console.log("I am pear!");}
   pear(); // 内部调用
} var instant = new fruit.banana();
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. MIPI D-PHY 简写收集

    Acronyms APPI         Abstracted PHY-Protocol InterfaceBER            Bit Error Rate 417 CILControl ...

  2. Torque2D MIT 学习笔记(27) ---- ImageFont的使用以及字体ImageAsset的工具生成

    前言 ImageFont继承于SceneObject,是一个场景对象,支持例如旋转,缩放,移动加速度以及物理碰撞等一切Torque中场景对象的一切功能. ImageFont只支持ASCII编码表中的3 ...

  3. 《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的期望

    在关于离散型随机变量函数的期望的讨论中,我们很容易就得到了如下的等式: 那么推广到连续型随机变量,是否也存在类似的规律呢? 即对于连续型随机变量函数的期望,有: 这里给出一个局部的证明过程,完整的证明 ...

  4. 让x86的android模拟器能模拟arm架构系统

    网上介绍共计三种模拟器比较常用,分别是bluestacks.andy和Genymotion,前者支持ARM架构,中者支持远程控制,后者启动速度快,各有优缺点. 如果要用genymotion模拟arm的 ...

  5. ExtJs 4: How To Add Grid Cell Tooltip

    最近忙一个项目的时候需要实现鼠标移到grid的某一行上提示消息.花了半天时间才解决.在网上找很久终于有找到一个有用的.我的版本是extjs4. 效果如图 Ext.onReady(function () ...

  6. js生成随机数的方法实例总结

    js生成随机数主要用到了内置的Math对象的random()方法.用法如:Math.random().它返回的是一个 0 ~ 1 之间的随机数.有了这么一个方法,那生成任意随机数就好理解了.比如实际中 ...

  7. 规则引擎QLExpress的简单应用

    QLExpress 是一个轻量级的类java语法规则引擎,作为一个嵌入式规则引擎在业务系统中使用.让业务规则定义简便而不失灵活.让业务人员就可以定义业务规则.支持标 准的JAVA语法,还可以支持自定义 ...

  8. 【Android - V】之Toolbar的使用

    Toolbar是Android V7包中的一个控件,用来代替Action Bar作为界面的头部标题栏布局.Toolbar相对于Action Bar的特点是更加灵活,可以显示在任何位置. 首先先来看To ...

  9. Java堆栈详解 .

    1. Java中堆栈(stack)和堆(heap) (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据 ...

  10. android 24 设置与桌面相同的action和category

    设置与桌面相同的action和category 安卓系统桌面也是一个activity,安卓桌面的action和category是: <activity android:name="co ...