在这里必须要提一句的是,this指向是学习js必须要掌握的(必须),再开始之前先看底部的总结,然后回上面看例子便一目了然。

例子1:

  1. function a(){
  2. var user = "TangSir";
  3. console.log(this.user); //undefined
  4. console.log(this); //Window
  5. }
  6. a();
    看总结第2条,这里函数本身没有被父级对象调用,那么这里就指向window
  1. function a(){
  2. var user = "TangSir";
  3. console.log(this.user); //undefined
  4. console.log(this);  //Window
  5. }
  6. window.a();
    可以发现是一样的,这是因为window是全局对象,这里的a是被window点出来的,所以指向window(在这里也可以把window理解为a的父级,那么就是总结第3条)

    例子2
  1. var o = {
  2. user:"TangSir",
  3. fn:function(){
  4. console.log(this.user); //TangSir
  5. }
  6. }
  7. o.fn();
    这里的this指向o(总结第3条)
  1. var o = {
  2. user:"TangSir",
  3. fn:function(){
  4. console.log(this.user); //TangSir
  5. }
  6. }
  7. window.o.fn();
    这里加了个window,但是fn的父级还是o,是o调用了它(总结第3条)
  1. var o = {
  2. a:12,
  3. b:{
  4. a:14,
  5. fn:function(){
  6. console.log(this.a); //14
  7. }
  8. }
  9. }
  10. o.b.fn();
    这里父级是b,那么this指向b(总结第3条)
  1. 例子3
  1. var o = {
  2. a:12,
  3. b:{
  4. a:14,
  5. fn:function(){
  6. console.log(this.a); //undefined
  7. console.log(this); //window
  8. }
  9. }
  10. }
  11. var j = o.b.fn;
  12. j();
    这里为何是undefined而不是14?是谁最后调用了它,这里是j(),那么this只能是window(总结第1条)
  1. 例子4
  1.  
  1. function Fn(){
  2. this.user = "TangSir";
  3. }
  4. var a = new Fn();
  5. console.log(a.user); //TangSir
    构造函数的this指向函数实例本身,这里赋给了a,等于赋值了一份给了a,那么a.user肯定也是TangSir(总结第5条)
  1.  
  1. 例子5
  1. function Fn()
  2. {
  3. this.user = 'TangSir';
  4. return {};
  5. }
  6. var a = new Fn();
  7. console.log(a.user); //undefined
    因为返回的是对象,所以this指向该对象,所有是undefined(总结第6条)
  1. function Fn()
  2. {
  3. this.user = 'TangSir';
  4. return function(){};
  5. }
  6. var a = new Fn();
  7. console.log(a.user); //undefined
  1. function同样是对象,所以this指向该对象,所有是undefined(总结第6条)
  1. function Fn()
  2. {
  3. this.user = 'TangSir';
  4. return 1;
  5. }
  6. var a = new Fn();
  7. console.log(a.user); //TangSir
    这里this指向函数实例本身,所以是TangSir(总结第6条)
  1. function Fn()
  2. {
  3. this.user = 'TangSir';
  4. return undefined;
  5. }
  6. var a = new Fn();
  7. console.log(a.user); //TangSir
  1. 这里this指向函数实例本身,所以是TangSir(总结第6条)
  1. function Fn()
  2. {
  3. this.user = 'TangSir';
  4. return null;
  5. }
  6. var a = new Fn();
  7. console.log(a.user); //TangSir
  1. 函数里有null比较特殊,这里this指向函数实例本身,所以是TangSir(总结第6条)
  1. 例子6
  1. var obj = {
  2. name:"TangSir",
  3. fn:function(){
    fn1=()=>{
    console.log(this.name); //TangSir
  4. }
    fn1();
  5. }
  6. }
  7. obj.fn();

    这里箭头函数父级是fn,去掉父级后,fn1()此时的父级就是obj,那么this.name自然是TangSir(总结第6条和第3条)

  1. 例子7
  1.  
  1. var o = {
  2. a:12,
  3. b:{
  4. a:14,
  5. c:{
    a:15,
    d:function(){
    console.log(this.a); //15
    function e(){
    console.log(this.a); //undefined
    f();
    }
    e();
    function f(){
    console.log(this.a); //undefined
    }
    g=()=>{
    console.log(this.a); //15
    }
    g();
    }
    }
  6. }
  7. }
  8. o.b.c.d();
    这里第一个console15(总结4),第二和第三个consoleundefined,不然理解,它们的调用时f()和e(),所以是undefined,第三个是箭头函数,根据例子6结合总结第7条,得出15

总结:

1、this在函数定义的时候是没办法确定指向的,只有函数执行的时候,最后谁调用了它才能确定this指向谁

2、如果函数中有this,但是函数本身没有被父级(上一级)对象调用,那么就指向window

3、如果函数中有this,且函数本身被父级(上一级)对象调用,那么this就指向上一级对象

4、如果函数中有this,且函数中有多个对象,尽管函数被最外层对象调用,但this仍然指向父级(上一级)对象

5、构造函数中this,指向构造函数实例,如果创建的实例赋给对象,那么等于复制了一份给对象,该对象也拥有实例中的this(new出来的构造函数可以改变this指向)

6、构造函数中带return,返回值若是对象,this指向的是那个返回的对象,返回值若是null,this还是指向那个构造函数实例

7、es6中=>箭头函数中的this,去掉当前函数的父级(上一级)对象,再看this指向谁,此时指向谁就是谁(结合第3条)

彻底搞懂js this指向问题的更多相关文章

  1. 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    作为一名前端工程师,必须搞懂JS中的prototype.__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞 ...

  2. 让你彻底搞懂JS中复杂运算符==

    让你彻底搞懂JS中复杂运算符== 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一. 在仔细阅读了ECMA ...

  3. 彻底搞懂 JS 中 this 机制

    彻底搞懂 JS 中 this 机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 目录 this 是什么 this 的四种绑定规 ...

  4. 一文搞懂 js 中的各种 for 循环的不同之处

    一文搞懂 js 中的各种 for 循环的不同之处 See the Pen for...in vs for...of by xgqfrms (@xgqfrms) on CodePen. for &quo ...

  5. 彻底搞懂js __proto__ prototype constructor

    在开始之前,必须要知道的是:对象具有__proto__.constructor(函数也是对象固也具有以上)属性,而函数独有prototype 在博客园看到一张图分析到位很彻底,这里共享: 刚开始看这图 ...

  6. 通过一张简单的图,让你彻底地搞懂JS的==运算

    大家知道,JavaScript中的==是一种比较复杂运算,它的运算规则很奇怪,很容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一. 在仔细阅读ECMAScript规范的基础上,我画了一 ...

  7. 晨叔技术晨报: 你真的搞懂JS中的“值传递”和“引用传递”吗?

    晨叔周刊,每周一话题,技术天天涨. 本周的话题是JS的内存问题(加入本周话题,请点击传送门). 图 话题入口 今天的技术晨报来,就来谈谈JS中变量的,值传递和引用传递的问题.现在,对于很多的JSer来 ...

  8. 一文彻底搞懂JS前端5大模块化规范及其区别

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14577243.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  9. Spirit带你彻底搞懂JS的6种继承方案

    JavaScript中实现继承的6种方案 01-原型链的继承方案 function Person(){ this.name="czx"; } function Student(){ ...

随机推荐

  1. 重看 mb volatile atomic

    在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的.为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执 ...

  2. redis重点ppt

  3. python之 《zip,lambda, map》

    1.zip 对于zip我们一般都是用在矩阵上 eg: a = [1,2,3] b = ['a', 'b', 'c'] x = zip(a, b) print(x) print(list(x)) 结果是 ...

  4. 入坑 docsify,一款神奇的文档生成利器!

    layout: postcategory: javatitle: 入坑 docsify,一款神奇的文档生成利器!tagline: by 沉默王二tags: - java Guide 哥是我认识的一个非 ...

  5. Apache Flink Dashboard未授权访问导致任意Jar包上传漏洞

    漏洞危害 攻击者无需Flink Dashboard认证,通过上传恶意jar包 csdn-[漏洞复现]Apache Flink任意Jar包上传导致远程代码执行 freebuf-Apache Flink ...

  6. bWAPP----Mail Header Injection (SMTP)

    Mail Header Injection (SMTP) 本地没有搭环境,没法演示,附上转载的 https://www.acunetix.com/blog/articles/email-header- ...

  7. 精尽MyBatis源码分析 - MyBatis初始化(四)之 SQL 初始化(下)

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  8. MindManager使用教程:如何导出HTML5交互式导图

    Mindmanager思维导图软件有着友好的用户界面以及丰富的思维导图制作功能.再搭配与Microsoft 软件的无缝集成功能,使得这款思维导图软件越来越受到职场人士的喜爱. 不仅是作为制作思维导图的 ...

  9. guitar pro系列教程(二十一):Guitar Pro在乐谱上的工作【一】

    当我们使用Guitar Pro写好一首乐谱之后,通常在乐谱上还会有哪些操作呢?对于刚接触{cms_selflink page='index' text='Guitar Pro'}的朋友们肯定还是不熟悉 ...

  10. web自动化测试--iframe切换

    什么是iframe切换,我们在测试web网页过程中,可能会遇到一个网页中嵌套另一个网页的情况,如下图,就是一个ifame嵌套的例子 我们如何切换呢,别急,webdriver里有方法,可以切换到ifra ...