this指向问题以及修改函数的this指向方法

1、什么是this

this表示对象
取决于函数调用

(this表示对象=>当前对象=>当前环境对象=>函数运行时环境对象)

this就是函数运行时所在的环境对象

(取决于函数调用=>不同场合,this有不同的值)

函数的不同使用场合,this有不同的值。

1、this永远指向对象
(JS中一切皆对象,window也是对象)
2、this指向取决于函数调用的位置
(this指向是不定的,无法在事先声明时就得知它的具体指向,因此只有在调用时才能得知它的指向)
3、this只能在函数体内部使用
(this是函数运行时,内部自动生成的一个对象(执行环境上下文,也称环境对象),this即函数内部环境对象本象,因此只能在函数内部使用)
4、箭头函数无视上述规则,且优先级最高
(箭头函数中this指向在声明处决定,指向作用域链的父级)

在这里插入图片描述

2、核心理解

场景优先级
箭头函数 > new > 显示绑定(call/apply/bind)> 隐式绑定(上下文对象obj) > 默认绑定(严格模式undefined,非严格为window)
注:
定时器setTimeout,setInterval中分两种情况,具体看下面例子
闭包或自执行函数被调用可以看做是接收了一个函数字符串,同样要看该字符串函数被调用的环境对象,具体看下面例子。

3、this指向详细例子

3.1 箭头函数中调用 箭头函数的this指向上一级环境对象

function fn() {setTimeout(() => {console.log(this.a);}, 1000);
}var obj = {a: 20,fn,
};fn.call(obj); // 20,这里可以理解为调用了obj.fn();

3.2 new实例调用 指向实例化出来的对象

function Person(name, age) {this.name = name;this.age = age;
}
const a = new Person('itachi', 18);
console.log( a.name ); // 这里new Person()构造函数内部的this指向了实例对象,
//即this=>a 所以this.name === a.name === 'itachi'

3.3 显示绑定(call/apply/bind) 绑定到指定的对象

可以参见箭头函数实例
var obj = {age: 20,fn:function (name) {console.log(this.name + '今年' + this.age + '岁')}
};
const a = { }
obj.fn.call( a , 'itachi'); // 执行了a.fn('itachi');'itachi'今年20岁
//这里可以理解为将obj中的this绑定到 a 
//让a拥有了obj中的方法fn(),并调用了 a.fn ('itachi');

3.4 隐式绑定(上下文对象obj)

function fn() {console.log(this.name);
}
var obj = {name: 'itachi'
};
// 调用 fn(..) 时把 this 绑定到 obj
obj.fn(); //itachi

3.5 默认绑定(严格模式undefined,非严格为window)

function fn() {console.log(this.a);
}
a = 10;
fn(); // 相当于window.fn()  输出10
function fn() {'use strict';console.log(this.a);
}
a = 10;
fn(); //相当于undefined.fn() 
//输出 TypeError: Cannot read property 'a' of undefined

3.6 定时器情况 定时器setInterval或setTimeout是window对象内置的一个方法

var obj = {fun:function(){return this ;}
}
​//此时还没执行fn,后面没跟(),即只是作为一堆字符串将其传了过去,执行的时候已经是1000ms以后了,这时是window.setInterval在执行
setInterval(obj.fn,1000);      // this指向window对象
//传入时就执行了,因此this指向的是obj对象
setInterval('obj.fn()',1000);  // this指向obj对象

3.7 函数作为闭包或自执行函数被调用 意味着这个函数不符合以上任意一种调用方式 因为闭包并不属于这个对象的属性或方法。所以在闭包中的this是指向window的

var name = “window”;
var obj={name: “Object”;getName: function(){return function(){return this.name;}}
};
var myobj = obj.getName(); //myobj接收到匿名函数(可以看做以字符串形式接收)
//myObj === 'function(){return this.name;}'  
console.log(myobj());  //  Window  相当于 return window.name
console.log(obj.myobj());  //  Object  相当于 return obj.name

3.8 在绑定事件中this指向—>当前事件对象

document.onclick = function () {console.log(this);
}

4、总结

this表示函数调用时的环境对象(执行上下文)
根据函数调用的不同场景,this指向也不同在箭头函数中:this指向作用域链的父级环境  在定时器中this指向--->Window  
通过new实例化时:this指向新实例化出来的对象  在对象中this指向--->当前对象   在构造函数中this指向--->实例对象
通过call/apply/bind调用时:this将绑定到指定的对象 通过上下文(对象)调用时:this指向上下文(该对象)
通过一般函数内部调用时:严格模式this指向undefined,否则指向全局对象   普通函数this指向--->Window

5、修改this指向三张方法的格式以及注意事项:

call  apply:改变this的指向 ,call直接调用,而apply需要重新调用这个函数
call传参数:call(this指向的,参数1,参数2...);
apply传参数:apply(this指向的,[参数1,参数2...]);     --->apply传参数是一个数组
bind传参数:bind

5.1 强制修改this指向的调用格式:

fn1.call(obj);call() 方法的第一个参数必须是指定的对象,然后方法的原参数,挨个放在后面。
(1)第一个参数:传入该函数this执行的对象,传入什么强制指向什么;
(2)第二个参数开始:将原函数的参数往后顺延一位
函数名.call()function fun() {console.log(this);  // 原来的函数this指向的是 Window
}
fun();function fun(a, b) {console.log(this); // this指向了输入的 字符串callconsole.log(a + b);
}
//使用call() 方法改变this指向,此时第一个参数是 字符串call,那么就会指向字符串call
fun.call('call', 2, 3)  // 后面的参数就是原来函数自带的实参
fn1.apply(obj);
apply() 方法的第一个参数是指定的对象,方法的原参数,统一放在第二个数组参数中。
(1)第一个参数:传入该函数this执行的对象,传入什么强制指向什么;
(2)第二个参数开始:将原函数的参数放在一个数组中 
用法: 函数名.apply()
function fun() {console.log(this);  // 原来的函数this指向的是 Window
}
fun();function fun(a, b) {console.log(this); // this指向了输入的 字符串applyconsole.log(a + b);
}
//使用apply() 方法改变this指向,此时第一个参数是 字符串apply,那么就会指向字符串apply
fun.apply('apply', [2, 3])  // 原函数的参数要以数组的形式呈现```
fn1.bind(obj)();
bind() 方法的用法和call()一样,直接运行方法,需要注意的是:bind返回新的方法,需要重新
调用
是需要自己手动调用的
用法: 函数名.bind()
function fun() {console.log(this);  // 原来的函数this指向的是 Window
}
fun();function fun(a, b) {console.log(this); // this指向了输入的 字符串bindconsole.log(a + b);
}
//使用bind() 方法改变this指向,此时第一个参数是 字符串bind,那么就会指向字符串bind
let c = fun.bind('bind', 2, 3);
c(); // 返回新的方法,需要重新调用
// 也可以使用下面两种方法进行调用
// fun.bind('bind', 2, 3)();
// fun.bind('bind')(2, 3);

5.2 强制修改this指向的传参语法:


fn1.call(obj, 1, 2);fn1.apply(obj, [3, 4]);fn1.bind(obj)(5, 6);    // bind传参在react框架用的比较多些

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/645735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch深度学习实战(32)——DCGAN详解与实现

PyTorch深度学习实战(32)——DCGAN详解与实现 0. 前言1. 模型与数据集分析1.1 模型分析1.2 数据集介绍 2. 构建 DCGAN 生成人脸图像小结系列链接 0. 前言 DCGAN (Deep Convolutional Generative Adversarial Networks) 是基于生成对抗网络 (Convolution…

PWN入门Protostar靶场Stack系列

Protostar靶场地址 https://exploit.education/protostar/溢出 源码分析 #include <stdlib.h> #include <unistd.h> #include <stdio.h>int main(int argc, char **argv) {volatile int modified; //定义一个变量char buffer[64]; //给…

Git 入门精讲

我们为什么要学习git&#xff1f; 就当下的发展而言&#xff0c;只要你从事开发就一定会接触git。作为最强大的分布式版本控制器&#xff0c;git 与 svn 有着本质上的区别。 Git是一种分布式版本控制系统&#xff0c;每个开发者都可以在本地维护完整的代码库&#xff0c;可以离…

c++ 加密与解密代码(普通加密 + 凯撒加密 + 图灵来了都解不开的加密)

当你和你的好朋友聊天的时候&#xff0c;你们的聊天内容很容易就被看出来&#xff0c;那么小天狼星这边可以给到一些建议~~ 一、用另一种语言 通常来说&#xff0c;使用除中文和其他常用语言外的语言是一个优秀的选择&#xff01; 例如&#xff1a;乌伯克语、阿亚帕涅科语。 …

智能泊车,再上热搜

编者按&#xff1a;相比于行车&#xff0c;低速可控场景&#xff0c;更有利于泊车功能快速迭代。同时&#xff0c;对于部分消费者来说&#xff0c;泊车智能化也是加分项。 智能泊车赛道&#xff0c;正在重新成为各路势力争夺的焦点。而上一次“高潮”&#xff0c;要追溯到2018年…

开源客户沟通平台Chatwoot账号激活问题

安装docker docker-compose 安装git clone https://github.com/chatwoot/chatwoot 下载之后根目录有一个docker-compose.production.yaml将其复制到一个目录 重命名 docker-compose.yaml 执行docker-compose up -d 构建 构建之后所有容器都安装好了 直接访问http://ip:3…

护眼台灯怎么选——明基、书客、孩视宝实测横评

最近护眼台灯的热度真是不小&#xff0c;许多博主纷纷推荐。考虑到孩子即将放寒假&#xff0c;市场上的产品也是五花八门&#xff0c;于是我决定认真研究一下&#xff0c;找出其中的水货和宝藏产品。我挑选了市场上口碑较好的3款产品进行深入评估&#xff0c;主要从照度、显色指…

Revit二次开发 设置材质

设置此处材质&#xff0c;需要在材质浏览器中创建材质&#xff0c;根据材质名字设置此材质。 代码如下&#xff1a; Material material new FilteredElementCollector(doc).OfClass(typeof(Material)).FirstOrDefault(x > x.Name "窗框") as Material; Element…

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹 1.安裝pip install google-generativeai 2.至 gemini pro 取 api key 3.撰寫如下文章:(方法一) import json import requests import base64 import streamlit as st 讀取圖片檔案&#xff0c;並轉換成 Base64 編…

Android SeekBar 进度条圆角

先看下效果图&#xff1a; 之前&#xff1a; 优化后&#xff1a; 之前的不是圆角是clip切割导致的 全代码&#xff1a; <SeekBarandroid:layout_width"188dp"android:layout_height"wrap_content"android:background"null"android:focusa…

风速预测 | Python基于CEEMDAN-CNN-Transformer+ARIMA的风速时间序列预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 CEEMDAN-CNN-TransformerARIMA是一种用于风速时间序列预测的模型&#xff0c;结合了不同的技术和算法。收集风速时间序列数据&#xff0c;并确保数据的质量和完整性。这些数据通常包括风速的观测值和时间戳。CEEMDAN分…

使用Spring Boot实现基于HTTP的API

Spring Boot是一个用于简化Spring应用程序开发的框架&#xff0c;它提供了一系列的开箱即用的功能&#xff0c;使得快速构建RESTful Web服务和基于HTTP的API变得简单。以下是使用Spring Boot实现基于HTTP的API的步骤&#xff1a; 添加依赖&#xff1a;在Maven项目中&#xff0c…

企业能源消耗监测管理系统是否可以做好能源计量与能耗分析?

能源消耗与分析是能源科学管理的基础&#xff0c;也可促进能源管理工作的改善&#xff0c;在企业中能源管理系统的作用也愈加重要。 首先&#xff0c;能源计量是能源管理的基础&#xff0c;通过能源精准计老化&#xff0c;容易出现测量设备不准确以及其他一些人为因素原因导致…

pve7.x、8.x版本一键升级、换源、优化工具脚本推荐

每次安装完pve之后都需要、换各种debain源、pve源、lxc源等、去掉弹窗、合并local-lvm等一系列的工作。还有玩硬件直通的优化。 偶然发现网上有大佬编写的一键脚本&#xff0c;pve_source 官网地址pve_source - X86派 - 迷你硬件玩家集中地 需要注册登录后能看到最新的地址 …

Oracle BIEE 示例(一)数据透视表2

1 背景 版本:BIEE 12C 视图:数据透视表 实现内容(顺序与具体内容不一致): 2 空列显示(方法一) 2.1 问题 列为空时,标题栏不显示信息。 2.2 期望 即使数据为空,也要显示列名。 2.3 官方资料 2.3.1 操作步骤 2.3.1.1 要在分析级别关闭空值隐藏,请执行以下操作…

操作无法完成,因为文件已在Windows资源管理器中打开,如何解决?以及如何将哔哩哔哩下载好的视频导出到电脑中播放?— 以vivo手机为例

前言 想删除流氓软件的时候&#xff0c;提示操作无法完成&#xff0c;因为文件已在Windows资源管理器中打开&#xff0c;但打开任务管理器&#xff0c;似乎又没有符合的正在执行的程序&#xff0c;更别说打开让人看到头疼的资源监视器了&#xff0c;本文将用一招解决如上问题 …

从一个main.cpp文件开始构建Qt项目【浅析】

目录 操作步骤 编译阶段 尝试运行 操作步骤 最初只有一个main.cpp文件。 然后在Qt的mingw命令行中进行以下操作&#xff1a; 这样就会在main.cpp的路径下生成一个.pro文件&#xff1a; 用QC打开后是这个样子&#xff1a; 所以在这里 qmake -project 的作用就是生成一个.…

【开源】基于JAVA语言的假日旅社管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿评论4.3 查询民宿新闻4.4 新建民宿预订单4.5 查询我的民宿预订单 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的假日旅社…

配置路由策略案例

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 厦门微思网络​​​​​​ https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom Linux\RHCE\RHCE 9.0\RHCA\ Oracle O…

1秒解决“整合磁盘时出错: 指定的虚拟磁盘需要进行修复”

引言 Linux初学者会时常报以下的错误&#xff0c;导致虚拟机打不开 原因 总的来说&#xff0c;就是没有正常关闭虚拟机导致的虚拟磁盘 (.vmdk)本身有一个磁盘保护机制&#xff0c;为了防止多台虚拟机同时访问同一个虚拟磁盘 (.vmdk)带来的数据丢失和性能削减方面的隐患&#…