本文来自 @position_柚子,地址:https://juejin.im/post/5995c7a76fb9a0247a60c407

在平时的代码中,相信大家经常用到 this,可是你真的明白此 this 真的是你认为的 this 吗?今天柚子君总结了一下平时用到的 this 的场景,大家走过路过不要错过啊~

首先咱们先来看一下《JavaScript 高级程序设计》上是怎么说的。

this 对象是在运行时基于函数的执行环境绑定的:在全局函数中,this 等于 windows,而当函数被作为某个对象的方法调用时,this 等于那个对象。

还有一种情况,在《深入理解 ES6》一书中写道:

如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,且不能通过 call()、apply() 或 bind() 方法来改变 this 的值。

首先看一下非箭头函数的情况:

一、普通函数调用

这是一个普通的函数声明,在这种情况下,this 是指向 window 的:

var test = '哈哈哈';
function thisHandler() {
console.log('test:',this.test,'this:',this);
}
thisHandler() // test: 哈哈哈 this: window

其实上面的代码就相当于 window 调用 thisHandler(),所以这时 this 指向 window

var b = '哈哈哈';
function thisHandler() {
console.log('b:',this.b,'this:',this);
}
window.thisHandler() // b: 哈哈哈 this: window

二、作为对象的方法调用

当作为对象的方法被调用时,this 这时就指向调用它的对象。

var thisHandler = {
name: "柚子",
test: function(){
console.log('my name:',this.name);
}
}
thisHandler.test() // my name: 柚子

再来一个栗子:

var thisHandler = {
name: "柚子",
fn: {
name: '芒果',
test: function() {
console.log('my name:',this.name);
}
}
}
thisHandler.fn.test() // my name: 芒果

这时 this 指向的是对象 fn 了,所以,关于对象调用这一点明白了吗,如果明白了,那没关系,接着看下一个强化题:

var name = '柚子'
var thisHandler = {
name: "芒果",
fn: {
name: '糖果',
test: function(){
console.log('my name:',this.name);
}
}
}
var testHandler = thisHandler.fn.test
testHandler()

这里是一秒钟分割线

哒哒哒,答对了,这里的 this 指向的 window,那么这是为什么呢,哪位小盆友来回答一下。举手:

上面说到了,this 指向的是最后调用它的对象,第一步是赋值给了 testHandler,最后执行的那一句相当于 window.testHandler()。所以这里的 this 指向的是 window。最后输出的就是 my name: 柚子

哒哒哒,真聪明,来闯下一关~

三、构造函数的调用

var name = '柚子'
function Bar() {
this.name = '芒果'
} var handlerA = new Bar();
console.log(handlerA.name); // 芒果
console.log(name) // 柚子

其实要明白为什么会是这样一个结果,咱们就要来聊聊 new 做了哪些事情。

  • 创建类的实例。这步是把一个空的对象的 __proto__ 属性设置为 Bar.prototype
  • 初始化实例。函数 Bar 被传入参数并调用,关键字 this 被设定为该实例。
  • 返回实例。

弄明白了 new 的工作内容,自然而然的也明白了上面输出的原因。

Bar() 中的 this 指向对象 handlerA,并不是全局对象。

四、apply / call 调用

使用 apply 方法可以改变 this 的指向。如果这个函数处于非严格模式下,则指定为 nullundefined 时会自动指向全局对象(浏览器中就是window对象)。

var name = '芒果';
var thisHandler = {
name: "柚子",
test: function(){
console.log('my name:',this.name);
}
}; thisHandler.test(); // my name: 柚子
thisHandler.test.apply(); // my name: 芒果

四、箭头函数

在《深入理解 ES6》一书中可以知道箭头函数和普通函数的一个不同之处就在于 this 的绑定。

箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值。如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this;否则,this 的值会被设置为 undefined

var name = '柚子'
var thisHandler = {
name: '芒果',
test:() => {
console.log('my name:',this.name,'this:',this);
}
} thisHandler.test(); // my name: 柚子 this: Window

这时 this 不是指向 thisHandler,而是 Window

关于 this 的使用和体会还是要在平时运用中理解,先了解其原理,那么在使用的时候就如鱼得水啦。

前端读者 | 嗨,你知道this吗的更多相关文章

  1. 前端读者 | Web App开发入门

    本文来自互联网 自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词 - Web App(意为基于WEB形式的应用程序).业界关于Web App与Nativ ...

  2. 前端读者 | 前端构建工具Gulp

    @羯瑞 整理 前言 前端工具现在层出不穷,网上搜下一大片,就看你怎么去使用了,基于项目看用什么样的构建工具.有的工具提供的功能还是非常强大的. FIS.百度团队的产品.现在百度的多个产品中使用.面向前 ...

  3. 前端读者 | 前端开发者调试面板vConsole

    来着微信团队开源的一个调试工具,[GitHub地址]https://github.com/Tencent/vConsole 一个轻量.可拓展.针对手机网页的前端开发者调试面板. 特性 查看 conso ...

  4. 前端读者 | 前端面试基础手册(HTML+CSS)

    本文来自@羯瑞:希望前端面试基础手册能帮助要找工作的前端小伙伴~~ HTML 前端需要注意哪些SEO? 合理的title.description.keywords:搜索对着三项的权重逐个减小,titl ...

  5. 前端读者 | Javascript设计模式理论与实战:状态模式

    本文来自 @狼狼的蓝胖子:链接:http://luopq.com/2015/11/25/design-pattern-state/ 在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将 ...

  6. 前端读者 | 由setTimeout引发的JS引擎运行机制的研究

    本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发 ...

  7. 前端读者 | 从一行代码里面学点JavaScript

    本文来自 @张小俊128:链接:http://www.html-js.com/article/A-day-to-learn-from-a-line-of-code-inside-the-JavaScr ...

  8. 前端读者 | 如何判断Javascript对象是否存在

    本文来自@阮一峰 Javascript语言的设计不够严谨,很多地方一不小心就会出错. 举例来说,请考虑以下情况. 现在,我们要判断一个全局对象myObj是否存在,如果不存在,就对它进行声明.用自然语言 ...

  9. 前端读者 | CSS三角形和饼图

    @羯瑞 三角形 .triangle{width:0;height:0;border-width:50px;border-style:solid;border-color:red blue green ...

随机推荐

  1. ios的hitTest方法以及不规则区域内触摸事件处理方法

    概述 在正常的使用场景中,我们处理了比较多的矩形区域内触摸事件,比如UIButton.UIControl.一般来说,这些控件的图形以及触摸区域都是矩形或者圆角矩形的.但是在一些特殊应用场景中我们有时不 ...

  2. 搭建JavaWeb应用开发环境

    下载和安装Tomcat服务器 下载Tomcat安装程序包:http://tomcat.apache.org/,下载一个zip版本,解压到本地即完成了Tomcat的安装. 测试是否安装成功:进入Tomc ...

  3. [LeetCode] 14. Longest Common Prefix ☆

    Write a function to find the longest common prefix string amongst an array of strings. 解法: 广度优先搜索:先比 ...

  4. 数据结构&图论:LCT

    HDU4010 类比静态区间问题->动态区间问题的拓展 我们这里把区间变成树,树上的写改删查问题,最最最常用LCT解决 LCT用来维护动态的森林,对于森林中的每一棵树,用Splay维护. LCT ...

  5. Linux系统查看系统信息

    1. CPU # lscpu # cat /proc/cpuinfo //可以知道每个cpu信息,如每个CPU的型号,主频等 2. 内存 # free -m # cat /proc/meminfo / ...

  6. PowerDesigner16 修改表或表的字段Name的时候不让Code不自动跟着变

    在修改表或表的字段Name的时候不让Code不自动跟着变,设置如下: tools-> General   Options-> Dialog 去掉勾选 Name To Code mirror ...

  7. 知问前端——Ajax提交表单

    本文,运用两大表单插件,完成数据表新增的工作. 一.创建数据库 创建一个数据库,名称为:zhiwen,表——user表,字段依次为:id.name.pass.email.sex.birthday.da ...

  8. 将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值,就可移动四个按钮

      将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值, 就可移动四个按钮               https://www.evernote.com/shard/s227/sh/78 ...

  9. Python ctypes 在 Python 2 和 Python 3 中的不同 // 使用ctypes过程中问题汇总

    In Python 2.7, strings are byte-strings by default. In Python 3.x, they are unicode by default. Try ...

  10. poj 3104 Drying(二分查找)

    题目链接:http://poj.org/problem?id=3104 Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...