说到this,入前端坑的人都知道这是JS初期语言毕竟之路。很多人(我就是)对于this的了解很模糊,或者不够全面。最近打算在反过来在看下es6,在es6中又出现了箭头函数对于this的理解有多了层认识。所以就在写一遍来加强自己的认知。


在讲this之前,我们先把作用域链在复习一下

在红宝书中对作用域链的描述有这么一句话:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问
简单来说,作用域链的作用就是在函数使用一个变量的时候,由近到远的查找有自身内部想最顶层也就是window的作用域中查找。

我们作用域链明白了,我们讲一下this.

this又分传统this和箭头函数中的this

传统this的指向:

1.this总是指向它的直接调用者。

2.在非严格模式下当没有调用者的时候,默认指向最顶层也就是window

3.在严格模式下('use strict')当没有调用者的时候,this就是undefined

4.在call、apply、bind绑定的时候,默认指向绑定的对象

箭头函数中this的指向:

1.箭头函数自身不包含this,它是继承与他所处的宿主对象的this。


光写概念,不说看得烦,我敲得也烦。直接上代码吧。

实例一:this指向它的直接调用者

var myObj = {
  myVal : 3,
  myFnc : function(){
    console.log(this);
  }
}
myObj.myFnc();//myobj
此时myObj调用了所以this指向于myObj;

实例二:非严格模式下没有调用者的时候

function myFnc(){
  console.log(this);
}
myFnc();//window
此时,因为没有调用者,所以this默认指向最顶层也就是window

实例三:严格模式下没有调用者的时候

function myFnc(){
  'use strict'
  console.log(this);
}
myFnc() //undefined
此时,没有调用者,又因为当前是严格模式所以打印出来的this是undefined

实例四:call、apply、bind绑定的时候function myFnc1(){

function myFuc1(){ 
 console.log(this);
}
function myFnc2(a,b){
  console.log(this);
}
myFnc2.call(myFnc1);//myFnc1 此时绑定的就是myFnc1,所以当前this的指向就是myFnc1;
call和apply的绑定机制大致是一样的,所以就不一一解释了。 var myObj = {
  myFnc :function(){
    setTimtout(function(){
      console.log(this);
    }.bind(this))
  }
}
myObj.myFnc();//myObj
因为在定时器函数中,没有调用者,所以默认指向window。又因为使用bind()方法给回调函数直接绑定了当前this指向,所以当前this指向就是myObj。

是不是感觉这么写很麻烦,当今的ES6的年代,还用啥bind绑定。如果需要返回当前函数伸手就是一个箭头函数

实例五:箭头函数简易版

var myObj = {
  myFnc :function(){
    setTimeout(() => {
      console.log(this)
    })
  }
}
myObj.myFnc();
因为箭头函数继承的是它的宿主对象的this,也就是继承的myFnc的this,而myFnc的This指向是myObj,所以打印出来的当前this指向就是myObj;

实例六:箭头函数嵌套版

var myObj = {
  myFnc :function(){
    function childFnc(){
      setTimeout(() => {
        console.log(this)
      })
    }
    childFnc();
  }
}
myObj.myFnc();
小小的思考一下。。。 如果你一瞬间就明白的话,那就表明你已经通关了。
由里到外的分析,你就会发现很简单。
因为箭头函数,当前this继承于它的宿主也就是childFnc。childFnc方法的执行,因为没有调用者。所以它的this指向的是window。所以当前打印的this指向就是window。

总结:


this指向简单的说就是谁调用就指向谁,没调用就指向window(严格模式undefined)

当出现箭头函数内的,就指向宿主元素。

深入理解JS各种this指向问题的更多相关文章

  1. 如何理解JS中this指向的问题

    首先,用一句话解释this,就是:指向执行当前函数的对象. 当前执行,理解一下,也就是说this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定.this到底指向谁?this的最终指向的 ...

  2. 关于js中this指向的理解总结!

    关于js中this指向的理解! this是什么?定义:this是包含它的函数作为方法被调用时所属的对象. 首先,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁 ...

  3. 简单理解js的this

    js的this是什么?关于这个东西,博客园里面有太多的解释了,不过,本人看了一下,感觉对this解释的有点复杂了,因此,本人在此给this一个简单易于理解的定义. this其实是js的一个对象,至于是 ...

  4. 从一个简单例子来理解js引用类型指针的工作方式

    <script> var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined conso ...

  5. 我这样理解js里的this

    关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...

  6. 深入理解js——prototype原型

    之前(深入理解js--一切皆是对象)中说道,函数也是一种对象.它也是属性的集合,你也可以对函数进行自定义属性.而JavaScript默认的给了函数一个属性--prototype(原型).每个函数都有一 ...

  7. 理解JS闭包

    从事web开发工作,尤其主要是做服务器端开发的,难免会对客户端语言JavaScript一些概念有些似懂非懂的,甚至仅停留在实现功能的层面上,接下来的文章,是记录我对JavaScript的一些概念的理解 ...

  8. 全面理解js面向对象

    前言 当今 JavaScript 大行其道,各种应用对其依赖日深.web 程序员已逐渐习惯使用各种优秀的 JavaScript 框架快速开发 Web 应用,从而忽略了对原生 JavaScript 的学 ...

  9. JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解

      前  言 JRedu 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于 ...

随机推荐

  1. vue 拦截器

    拦截器:请求发送之前和请求返回之后的处理 使用:1.config---dev.env.js 开发环境配置 2. prod.env.js 生产 API:'http://www.wpdic.com' 3. ...

  2. java 关于值引用、地址引用的问题

    8种基本引用类型 四种整数类型(byte.short.int.long) 两种浮点数类型(float.double) 一种字符类型(char) 一种布尔类型(boolean) 以及如String, f ...

  3. thinkphp 5 where 组合条件map数组or

    if($inviterId>0) { $arr = Db::table("tablename")-> where("pid=$inviterId") ...

  4. c# 重载运算符(ovveride operator)踩坑记,关于null比对

    场景描述: 需要比对两个版本的对应对象是否完全一致(每个属性值一致),不一致的导出报表颜色标识,以便提醒后续使用报表人员. 实现思路: 对象重载ToString方法,另实现一比对基类(为了通用)重载= ...

  5. JAVA多线程提高十三:同步集合类的应用

    1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...

  6. (一)Hadoop1.2.1安装——单节点方式和单机伪分布方式

    Hadoop1.2.1安装——单节点方式和单机伪分布方式 一.   需求部分 在Linux上安装Hadoop之前,需要先安装两个程序: 1)JDK 1.6(或更高版本).Hadoop是用Java编写的 ...

  7. Eclipse 断点调试

    Eclipse 开发专用的Debug模式,用于发现问题解决问题. 1. 设置断点,程序会在改位置停止. 2. 按F5(step into), F6(step over)执行.F5指跳入,逐语句.会进入 ...

  8. 【leetcode 简单】第三十九题 Excel表列名称

    给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如, 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> ...

  9. Openflow Plugin学习笔记1

    主入口 ConfigurableOpenFlowProviderModule是OpenFlowPlugin中启动加载的入口,如下: @Override public java.lang.AutoClo ...

  10. OkHttp与Cookie及Cookie的持久化

    http://blog.csdn.net/u011150924/article/details/52780931 http://blog.csdn.net/chen19960724/article/d ...