JS中的this指向

news2025/2/26 21:59:22

this的概念:

  1. 在js中,this的意思为“这个;当前”,是一个指针型变量,它动态指向当前函数的运行环境。

  2. 在不同的场景中调用同一个函数,this的指向也可能会发生变化,但是它永远指向其所在函数的真实调用者;如果没有调用者,就指向全局对象window。

普通函数:关于this,谁调用就指向谁,没有调用者,就指向全局对象window。
箭头函数:箭头函数的this指向于函数作用域所用的对象。

一、全局环境下的this指向

在全局作用域下,this始终指向全局对象window,无论是否是严格模式!

congsole.log()完整的写法是window.console.log(),window可以省略,window调用了console.log()方法,所以此时this指向window。

二、函数内的this

  • 普通函数内的this分为两种情况,严格模式下和非严格模式下。
1. 严格模式下:

直接test()调用函数,this指向undefined,window.test()调用函数this指向window。因此,在严格模式下, 我们对代码的的调用必须严格的写出被调用的函数的对象,不可以有省略或者说简写。

2. 非严格模式下:

非严格模式下,通过test()和window.test()调用函数对象,this都指向window。

三、对象中的this

对象内部方法的this指向调用这些方法的对象,也就是谁调用就指向谁

1. 一层对象:

调用obj.skill()方法,返回值为蒙犽,说明此时this指向obj。

2. 二层对象:

调用skill2()方法的顺序为,obj.obj2.skill2() ,返回值为鲁班,说明skill2()方法中的this指向obj2。

总结:

  1. 函数的定义位置不影响其this指向,this指向只和调用函数的对象有关

  2. 多层嵌套的对象,内部方法的this指向离被调用函数最近的对象

四、箭头函数中的this

箭头函数:this指向于函数作用域所用的对象。
  • 箭头函数的重要特征箭头函数中没有this和arguments,是真的没有!

  • 箭头函数没有自己的this指向,它会捕获自己定义所处的外层执行环境,并且继承这个this值,指向当前定义时所在的对象。箭头函数的this指向在被定义的时候就确定了,之后永远都不会改变。即使使用call()apply()bind()等方法改变this指向也不可以。

例子1:

  • 声明的是全局变量Obj,this指向箭头函数所在全局作用域的对象,即indow对象。

例子2:

  1. 由于show函数是箭头函数,所以自身不能绑定this,因此找它的上一级作用域。如果父级作用域还是箭头函数,就再往上找,一层一层的直到直到this的指向。

  2. window.show()返回值是window,所以this此时指向window;

  3. window.obj.show(),obj是对象,非箭头函数,所以找到这里就停止了,this绑定到obj上。window调用obj,所以obj中的this也指向window。

五、构造函数中的this

构造函数中的this是指向实例。

由上图可以看出,构造函数中的this指向构造函数下创建的实例

、原型链中的this

this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。

七、改变this指向的方法

1. call()
  • call(a, b, c)方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以。

示例:

//定义函数
function fn(n1,n2){
   console.log(this);  
   console.log(n1,n2)
}
//调用call()方法
fn.call();//=>this:window;
let obj = {fn:fn};
fn.call(obj);//=>this:obj;n1,n2:undefined
fn.call(1,2);//=>this: 1;n1=2,n2=undefined;
fn.call(obj,1,2);//=>this: obj;n1=1,n2=2;

//Call方法的几个特殊属性
//非严格模式下
fn.call(undefined);//this=>window
fn.call(null);//this=>window
//严格模式下
"use strict"
fn.call(undefined);//this=>undefined
fn.call(null);//this=>null
2. apply()
  • apply(a, [b])和call基本上一致,唯一区别在于传参方式,apply把需要传递给fn()的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn()一个个的传递。

  • //call()的传参方式
    fn.call(obj, 1, 2);
    //apply()的传参方式
    fn.apply(obj, [1, 2]);
    

示例:

//apply方法的使用和call方法基本相同,唯一的区别是,apply方法传参要求是数组类型的,数组内可以任意形式的数据
function fn (n1,n2){
    console.log(this);
    console.log(n1,n2)
    console.log(arguments)
}
let obj = {fn:fn};
//调用apply()方法
fn.applay(abj,[1,2]);
fn.applay(abj,1,2)//报错

fn.applay(abj,[11,'apply',{a:123}]);//注意第二个参数必须是数组,否则会报错
3. bind()
  • bind(a, b, c):语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8

  • bind与call的唯一区别就是call直接改变函数test的指向,而bind生成了一个新函数test2(),该函数改变了指向。

  • //call()方法:改变fn中的this,并且把fn立即执行
    fn.call(obj, 1, 2); 
    //bind()方法:改变fn中的this,fn并不执行
    fn.bind(obj, 1, 2); 
    

示例:

//bind和call方法调用形式类似,但是原理完全不同
fn.call(obj,10,20);//=>fn先执行,将fn内的this指向obj,并且把参数10,20传递给fn

fn.bind(obj,10,20)//bind是先将fn中的this指向obj,并且将参数10,20预先传递给fn,但是此时的fn并没有被执行,只有fn执行时this指向和传递参数才有作用
fn.bind(obj,10,20);//=>不会有任何输出
fn.bind(obj,10,20)();//=>调用后才会有输出

//=>需求:点击box这个盒子的时候,需要执行fn,并且让fn中的this指向obj
oBox.onclick=fn; //=>点击的时候执行了fn,但此时fn中的this是oBox

oBox.onclick=fn.call(opp); //=>绑定事件的时候就已经把fn立即执行了(call本身就是立即执行函数),然后把fn执行的返回值绑定给事件

oBox.onclick=fn.bind(opp);
//=>fn.bind(opp):fn调取Function.prototype上的bind方法,执行这个/* 
 * function(){
 *     fn.call(opp);
 * }
 */
oBox.onclick=function(){
   //=>this:oBox
    fn.call(opp);
}

相同点:

  • call、apply和bind都是JS函数的公有的内部方法,他们都是重置函数的this,改变函数的执行环节。

不同点:

  • bind是创建一个新的函数,而call和aplay是用来调用函数;
  • call和apply作用一样,只不过call为函数提供的参数是一个个地罗列出来,而apply为函数提供的参数是一个数组

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

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

相关文章

如何在uniapp中优雅地使用WebView

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 从webview页面传值到uniapp中 官方文档已经很详细了,这里给大家上我的实战代码&#xff0c;首先在webview页面中引入相关依赖&#xff1a; <!-- uniapp各平台依赖 --> <script type"tex…

用uniapp实现微信小程序的电子签名效果

✅作者简介&#xff1a;大家好我是瓜子三百克&#xff0c;励志成为全栈工程师的一枚程序猿&#xff0c;也是喜欢在学习和开发中记录笔记的小白博主&#xff01; &#x1f4c3;个人主页&#xff1a;瓜子三百克的主页 &#x1f525;系列专栏&#xff1a;uniapp前端 &#x1f496;…

vue项目实战-电商后台管理系统

项目简介&#xff1a; 该项目为电商后台的管理系统。设计了登录页面。 管理人员需要通过输入正确的用户名和密码才能登录。登陆成功之后进入管理页面&#xff1a; 管理页面由五个子模块组成&#xff1a;用户管理&#xff0c;权限管理&#xff0c;商品管理&#xff0c;订单管理…

ChatGPT对话数据备份

ChatGPT对话数据备份 文章目录ChatGPT对话数据备份1. 背景2. 其他&#xff08;失败的&#xff09;方法2.1 右键另存为2.2 直接copy html代码3. 编写Javascript脚本3.1 思路过程3.2 安装教程3.3 使用说明3.4 最终效果1. 背景 之前在ChatGPT更新时有好几天都无法查看过往对话&am…

webpack 面试题整理

文章目录webpack 面试题整理谈谈你对Webpack的理解Webpack的打包过程/打包原理/构建流程&#xff1f;Webpack中loader的作用/ loader是什么&#xff1f;常见的loader有哪些&#xff1f;Plugin有什么作用&#xff1f;/Plugin是什么常见的Plugin有哪些Webpack 插件的执行顺序&…

15套前端经典实战项目大合集,小白练手必备实战项目

15套前端经典实战项目大合集&#xff0c;悄悄练习&#xff0c;你会惊艳所有人。 今日我以内卷为荣&#xff0c;明日内卷以我为荣&#xff0c;不管学习哪门语言都要做出实际的东西来&#xff0c;这个实际的东西就是项目。 这里整理了15前端经典实战项目&#xff0c;每套都有完…

nodejs高版本降为低版本方案

1.首先通过控制面板应用卸载当前环境下的Node.js相关安装&#xff0c;并清理磁盘残存的文件夹等文件 2.下载nvm来管理node版本 官网&#xff1a;https://github.com/coreybutler/nvm-windows/releases 说在前面&#xff0c;贴一个error C:\Windows\system32>nvm use 12.10.…

web前端Vue 报错:Uncaught (in promise) TypeError: Cannot read properties of nu

前言 最近在写vue项目 在写自定义分页器的时候报了一个异常 知道错误却一直找不到解决方案 苦思冥想后 还是js的基础语法不扎实导致的&#xff0c;在此记录一下解决方案和思路 为以后的bug解决之路打下基础 错误提示 错误内容Uncaught (in promise) TypeError: Cannot read…

【HTML特效程序】① 给女神表白的程序(让女神看科技烟花),输入名字自动生成表白二维码

目录一、效果演示视频二、一步一步创建项目三、生成表白二维码的小链接一、效果演示视频 给女神表白的程序二、一步一步创建项目 &#x1f339; 在您的电脑上创建 love 文件夹 &#xff08;存放所有的资源和代码&#xff09; &#x1f339; 在 love 文件夹中创建 images 文件夹…

Vue 国际化之 vue-i18n 的使用

目录 一、安装 二、使用 1、准备语言包 2、准备翻译的语言环境 3、实现语言翻译 三、整合 ElementUI 语言包 1、扩展中文 2、扩展英文 3、使用扩展语言翻译 四、问题记录 五、扩展 vue3 中使用 vue-i18n 一、安装 npm install vue-i18n 如果在一个模块系统中使用…

elementUI使用el-upload上传文件写法总结及避坑,上传图片/视频到本地/服务器以及回显+删除

Element Upload 上传 Element Upload官方文档&#xff1a;el-upload 具体细节只看官方文档&#xff0c;本篇主要介绍避坑点和用法总结 注意点以及坑 本地上传想要回显图片视频&#xff0c;使用on-success是没办法再在上传后获取到本地文件路径后进行回显的&#xff0c;因为只…

若依(RuoYi )权限管理设计

前言 若依权限管理包含两个部分&#xff1a;菜单权限 和 数据权限。菜单权限控制着我们可以执行哪些操作。数据权限控制着我们可以看到哪些数据。 菜单是一个概括性名称&#xff0c;可以细分为目录、菜单和按钮&#xff0c;以若依自身为例&#xff1a; 目录&#xff0c;就是页…

TypeScript 学习笔记(十万字超详细知识点总结)

👉 本系列专栏:TypeScript从入门到精通 🖥️ NodeJS专栏:Node.js从入门到精通 📢 欢迎私信博主加入前端交流群🌹 知识目录 一、介绍1、JavaScript最大的问题2、什么是TypeScript3、JS , ES , TS 的关系4、为什么使用TypeScript5、配置TypeScript环境二、数据类型1、基…

下载、编译、安装、使用 vue-devtools

不少人都想下载 vue-devtools插件&#xff0c;但又不会做&#xff0c;今天我做个比较详细的笔记 查看当前的devtools的版本可以去这个网站看右侧的个v几点几的&#xff0c;就是版本号 github/vuejs/devtools 目录 第一个方法&#xff1a;使用极简插件 第一步&#xff1a;查…

Node.js | JavaScript也能写后端?

本文已收录于专栏⭐️ 《深入浅出Node.js》⭐️ 学习指南&#x1f4c3;&#x1f449;引入⭐️初识Node.js⭐️发展历史⭐️应用场景⭐️搭建环境&#x1f449;完结散花&#x1f449;参考文献&#x1f449;引入 如果读者是一个前端开发的同学&#xff0c;不知道你有没有过这样的…

jsoup的使用

本文在写作过程中参考了官方文档&#xff0c;传送门。 一、jsoup概述 jsoup 是一款基于 Java 的HTML解析器&#xff0c;它提供了一套非常省力的API&#xff0c;不但能直接解析某个URL地址、HTML文本内容&#xff0c;而且还能通过类似于DOM、CSS或者jQuery的方法来操作数据&…

Node.js和Vue的安装与配置(超详细步骤)

目录一、下载二、安装三、配置四、安装配置vue五、构建运行Vue项目一、下载 Node.js官网下载 大家根据自己的系统进行下载安装包&#xff08;我的电脑是windows10-64位&#xff0c;所以下载第一个&#xff09; 二、安装 点击下载的安装包进行安装 点击Next 打勾并点击Ne…

vue3 路由的使用

路由的使用 在传统的 Web 开发过程中&#xff0c;当需要实现多个站内页面时&#xff0c;以前需要写很多个 HTML 页面&#xff0c;然后通过 标签来实现互相跳转。在如今工程化模式下的前端开发&#xff0c;像 Vue 工程&#xff0c;可以轻松实现只用一个 HTML 文件&#xff0c;…

JavaScript:实现复制粘贴剪切功能

文章目录js实现复制粘贴功能方式一&#xff1a;原生方式实现复制粘贴剪切&#xff08;不推荐&#xff09;方式二&#xff1a;浏览器自带clipboard API实现复制粘贴&#xff08;推荐&#xff09;简介特点clipboard对象及相关APIClipboard.readText()Clipboard.read()Clipboard.w…

iframe标签的使用

iframe标签的使用1、什么是iframe2、iframe的元素属性3、iframe操作4、iframe 对象及属性5、创建iframe元素6、iframe之间的通信6.1、什么是主域名&#xff0c;什么是子域名(拓展)6.2、iframe之间的通信7、其他7.1、iframe自适应7.2、防嵌套网页7.2.1、浏览器端7.2.2、服务器端…