this 去哪?
this 去哪?
本文写于 2020 年 4 月 26 日
let obj = {
foo() {
console.log(this)
},
}
let bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
最后两行函数的值为什么不一样???
之前关于函数的文章里写过了,let bar = obj.foo可以让bar()和obj.foo()等价,那为什么 this 指向不一样?
在学 React 的时候,很多人会发现有个很烦人的操作,就是在constructor里面,需要bind(this)。
首先需要从函数的调用开始讲起。
ES5 里面有三种函数调用形式:
foo(p1, p2)
console.log('================')
obj.foo(p1, p2)
console.log('================')
foo.call(obj, p1, p2)
/*
* 或者apply或者bind,这三个都是用来绑定this的
*/
乍看之下,前两种简单,后面一种复杂。很多人就选择完全不使用后面的call()。
但实际上,后面的才是我们真正的写法,前面的都可以等价的变成该种写法:
func.call(context, p1, p2)
foo(p1, p2) 等价于 foo.call(undefined, p1, p2)
obj.foo(p1, p2) 等价于 obj.foo.call(obj, p1, p2)
很多人特别喜欢死记硬背这个 this 的指向,“谁调用 this 就指向谁”blablabla……
但实际上,this 是要为我们所用的,我想让你指向谁,你就要指向谁。我们不应该被它牵着走。
先看foo(p1, p2)中的 this 如何确定。
当你写下面代码时:
function foo() {
console.log(this)
}
foo()
等价于
function foo() {
console.log(this)
}
foo.call(undefined) // 可以简写为 foo.call()
按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:
如果你传的第一个参数是null或者undefined, window 对象就是默认的。因此上面的打印结果是 window。
如果希望这里的 this 不是 window 该怎么做呢?
很简单:
func.call(obj) // 那么里面的 this 就是 obj 对象了
再看obj.foo(p1, p2) 里的 this 如何确定:
let obj = {
foo() {
console.log(this)
},
}
obj.foo()
他本身的指向就是 obj 自己,所以写成call()也就是:obj.foo.call(obj)
回到最上面的代码。
let obj = {
foo() {
console.log(this)
},
}
let bar = obj.foo
obj.foo() // 转换为 obj.foo.call(obj),this 就是 obj
bar()
// 转换为 bar.call()
// 由于没有传 context
// 所以 this 就是 undefined
// 最后浏览器给你一个默认的 this —— window 对象
提一个有趣的用法:如果把函数放到数组里,然后数组[]调用函数,this 指向哪里呢?
function fn() {
console.log(this)
}
let arr = [fn, fn2]
arr[0]()
这里面的 this 是什么呢?
我们可以把arr[0]()理解为arr.0(),虽然后者的语法错了,但是形式与转换代码里的obj.foo(p1, p2)对应上了!
arr[0]() => arr.0() => arr.0.call(arr)
那么里面的 this 就是 arr 了。
总之,this 就是你 call 一个函数时,传入的第一个参数。
(完)
this 去哪?的更多相关文章
- 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观
前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...
- 就这么漂来漂去---一个毕业三个月的java程序员的裸辞风波
注:这并不是一篇技术文章,而是记录了我这几个月经历的入职,裸辞,找工作的心路历程,简单介绍一个博主的情况,我是16年毕业生,校招进了一家北京的公司,java开发,和很多年轻人一样,干了一段时间,我发现 ...
- 去IOE的一点反对意见以及其他
某天在机场听见两老板在聊天,说到他们目前销售的报表老跟不上的问题,说要请一个人,专门合并和分析一些发过来的excel表格,我真想冲上去说,老板,你需要的是一个信息处理的系统,你需要咨询么.回来一直耿耿 ...
- IM 去中心化概念模型与架构设计
今天打算写写关于 IM 去中心化涉及的架构模型变化和设计思路,去中心化的概念就是说用户的访问不是集中在一个数据中心,这里的去中心是针对数据中心而言的. 站在这个角度而言,实际上并非所有的业务都能做去中 ...
- JavaScript 函数节流和函数去抖应用场景辨析
概述 也是好久没更新 源码解读,看着房价蹭蹭暴涨,心里也是五味杂陈,对未来充满恐惧和迷茫 ...(敢问一句你们上岸了吗) 言归正传,今天要介绍的是 underscore 中两个重要的方法,函数节流和函 ...
- 回车去替换铵钮的click点击功能
某一时候,我们不想在form的所有必填的域均完成之后,再去使用mouse去点击铵钮来提交数据.而是直接按回车去focus提交的铵钮来提交. 可以写jQuery script程序:
- app使用微信支付成功后,点击返回到该app却跳到另外一个app去了
刚接手了公司iOS的两个APP, 现在碰到了这样一个问题: 有一台iPhone在一个APP中使用了微信支付,支付成功后,点击返回到该APP,结果却跳到了另外一个APP去了. 这两个APP都是公司开发的 ...
- [LeetCode] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- openwrt下部署adbyby去广告大师 免luci 带自启动,自动开启透明代理
最近朋友送了个360老路由器 C301,于是乎就掉进了智能路由器的坑, 玩智能路由器第一件事一定是去广告, 要么怎么对得起智能路由器- -! 路由器去广告当然首推广告屏蔽大师 www.adbyby.c ...
随机推荐
- centos简单命令备忘
1.查看当前目录 [root@instance-aif30iaj bin]# df -h 2.查看指定目录 在命令后直接放目录名,比如查看"usr"目录使用情况: [root@in ...
- ACM - 图论 - P3385 负环
P3385 负环 题目描述 给定一个 \(n\) 个点的有向图,请求出图中是否存在从顶点 \(1\) 出发能到达的负环. 负环的定义是:一条边权之和为负数的回路. 输入格式 本题单测试点有多组测试数据 ...
- 汽车最强大脑ECU和单片机是什么关系
先上图一张,据说这是某个F1赛车的动力总成ECU. 定睛一看,这不就是两个英飞凌的单片机的合体嘛. ECU的定义 ECU原来指的是engine control unit,即发动机控制单元,特指电喷发动 ...
- gulp详细基础教程
一.gulp简介 1.gulp是什么? gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器:它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成: ...
- java中final变量的用法
4.4 final变量 final变量的数值不能在初始化之后进行改变(你希望a=3,有很多用到a的场合, 你当然不能在程序中就用3来代替a). 比如: final int h = 0; 想像有一 ...
- 三种获取数据的方法fetch和ajax和axios
一 .fetch用法 ( 本人比较喜欢fetch,代码精简,虽说目前axios比较流行,但是fetch很多大厂已经开始用fetch开始封装了, 我觉得以后fetch会取代axios和ajax ) 1. ...
- jboss学习1之EJB和JBOSS的宏观理解
一.中间件(Middleware) 先来看一张图: 中间件,也就是图中的Middleware,他的作用是什么呢? 简单来说,中间件就是操作系统和应用程序之 ...
- Vue Element ui密码框校验
<el-form-item prop="repeat_Password" class="userName_color"> <el-input ...
- 【论文阅读】ICLR 2022: Scene Transformer: A unified architecture for predicting future trajectories of multiple agents
ICLR 2022: Scene Transformer: A unified architecture for predicting future trajectories of multiple ...
- 想减少代码量,快设置一个有感知的 Aware Spring Bean
摘要:正常情况下,Spring 中的 Bean 对 Spring 是无感知的,Spring 框架提供了这种扩展能力,能让一个 bean 成为有感知的. 本文分享自华为云社区<有感知的 Aware ...