三、使用apply()、call()、bind()方法修改this指向:
浏览器在调用函数时,每次都会向函数内部传递一些隐含的参数,this就是其中之一,this的指向是函数执行的上下文对象,而当函数的调用方式不同时,this所指向的这个上下文对象也是不一样的,常见的具体情况如下。
当以函数的形式调用时,this指向_ 全局对象window _:
function test() { console.log(this)}//输出内容(全局对象window):Window {window: Window, self: Window, document: document, name: '', location: Location, …}test()
当以方法的形式调用时,this指向 该方法的调用者:
var obj = { //当对象的一个属性为函数时,称这个函数为该对象的方法 test: function() { console.log(this) }}//输出内容(对象obj):{test: ƒ}obj.test()
当以构造函数的形式调用时,this指向 新创建的那个对象:
function Test() { //使用二元运算符instanceof来验证此时的这个this是Test()类的实例,即该构造函数创建出的新对象 console.log(this , this instanceof Test) }//输出内容(分别为新对象demo和布尔值true):Test {} truevar demo = new Test()
在事件的响应函数中,this指向 响应函数的绑定者:
<button id = 'btn'> 点我输出this</button>
var btn = document.getElementById('btn')//给按钮btn绑定一个点击事件btn.onclick = function() { console.log(this)}//点击按钮后的输出内容(按钮btn):<button id = 'btn'> 点我输出this </button>
使用apply()、call()、bind()方法改变this指向时,this的指向就是 _方法中所指定的那个对象_(详细示例见第三部分)。
被Vue所管理的函数为普通函数时(如 methods 、computed 、watch 等配置项中的函数是普通函数的形式时),其this指向 Vue的实例对象vm或组件实例对象vc(以后者为例):
//此为组件HelloWorld.vue内容:<template> <div class="hello"> <button @click="test()">点我输出this</button> </div></template> <script>export default { name: "HelloWorld",//举methods中的普通函数为例 methods: { test() { console.log(this) } },};</script>//点击按钮后输出内容为(组件实例对象vc):VueComponent {_uid: 5, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}
不被Vue所管理的函数若为箭头函数时(当methods、computed、watch等配置项中的定时器回调函数、ajax的回调函数都写为箭头函数的形式时),由于箭头函数的this总是指向词法作用域,即外层调用者,所以此时其this同样指向 Vue的实例对象vm或组件实例对象vc(以后者为例):
//以下为组件HelloWorld.vue的内容:<template> <div class="hello"> <button @click="test()">点我输出this</button> </div></template> <script>export default { name: "HelloWorld", methods: { test() { //开启定时器 setTimeout(()=> { console.log(this); }, 200); }, },};</script> <style scoped></style>//点击按钮200ms后输出内容为(组件实例对象vc):VueComponent {_uid: 2, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}
在 组件的自定义事件(下面的代码以此为例)、全局事件总线、消息订阅与发布 中,若其回调函数配置在methods中(见注释写法一),或是其回调函数为箭头函数(见注释写法二),则该回调函数的this指向也是 _Vue的实例对象vm或组件实例对象vc_(以后者为例):
//以组件的自定义事件为例,以下是App.vue的内容:<template> <div id="app"> <HelloWorld ref="demo"/> </div></template> <script>import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', components: { HelloWorld, }, //写法一:将事件回调放在methods中 methods:{ test() { //输出内容(组件实例对象vc):VueComponent {_uid: 1, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …} console.log(this) } }, mounted() { this.$refs.demo.$on('showThis',this.test) } //写法二:将事件回调写在mounted中,使用箭头函数的写法,不写methods中的test()方法 mounted() { //输出内容(组件实例对象vc):VueComponent {_uid: 1, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …} this.$refs.demo.$on('showThis', () => console.log(this)) }}</script>
//以下是HelloWorld.vue的内容:<template> <div class="hello"> <button @click="emitShowThis()">点我触发showThis事件</button> </div></template> <script>export default { name: "HelloWorld", methods: { emitShowThis() { //触发showThis事件 this.$emit('showThis') //解绑showThis事件(若在此时解绑,则点击按钮总共只进行一次输出) this.$off('showThis') } },};</script>
这种情况不多,因为 Vuex 可以替代组件的自定义事件、全局事件总线、消息订阅与发布,如会使用Vuex,则此种情况可以忽略。
另外,将上述三种情况分别反过来,则this的指向将不再为Vue的实例对象vm或组件实例对象vc_,_此时this指向 需要具体分析。
值得注意的是,虽然这三种方法都可以改变this的指向,但在使用时也稍有区别:
(1)在调用apply()或call()时,都会直接调用函数执行,但在调用bind()时,就不会调用函数执行,而是会返回一个this指向被修改好的新函数供我们调用。
(2)在传参时,第一个参数就是需要让this去指向的对象,若还有其他参数,在使用apply()时,需要将第二个及以后的参数封装到同一个数组中进行传递;在使用call()时,只需要将其他参数依次在第一个参数之后传递即可;在使用bind()时,第二个及以后的参数需要在新函数中传,传递方式同call()一样,无需封装。
_修改示例 _具体如下(第一部分中第2种情况下的this指向应为对象obj,现将其修改为window):
使用apply()方法修改this指向:
var obj = { test: function (val) { console.log(val, this) }}//输出内容(100和window):100 Window {window: Window, self: Window, document: document, name: '', location: Location, …}obj.test.apply(window, [100])
使用call()方法修改this指向:
var obj = { test: function (val) { console.log(val, this) }}//输出内容(200和window):200 Window {window: Window, self: Window, document: document, name: '', location: Location, …}obj.test.call(window, 200)
使用bind()方法修改this指向:
var obj = { test: function (val) { console.log(val, this) }}//输出内容(300和window):300 Window {window: Window, self: Window, document: document, name: '', location: Location, …}var demo = obj.test.bind(window)demo(300)
原网址: 访问
创建于: 2023-08-07 17:05:34
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论