【JavaScript】【分享】关于this

前言

本文旨在总结实践中关于this关键字的应用经验,期待读者在评论区留言指正与补充,以促进共同学习与进步。

方向

  1. 宿主环境为浏览器(网页),创建一个html文件用浏览器打开即可。如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>关于this</title></head><body><script>// 代码</script></body>
</html>
  1. 严格模式和非严格模式。
  2. 普通函数和箭头函数。
  3. bind,call,apply。
  4. new关键字。

1.为什么要用this?

看下面例子:

      Object.prototype.eat = function () {console.log(this.name);};const peach = {name: "peach",};  peach.eat();

原型最常被用作方法的容器。相似的对象都有相似的方法,所以将所有方法挂载到同一个共享原型上。那么,原型上的函数如何知道自己在执行的时候应该作用于哪个对象呢?这就要用到this了。
再看一个例子:

function eat() {console.log(this.name);}
const peach = {name: "peach",
};
const plum = {name: "plum",
};
eat.call(peach); // peach
eat.call(plum); // plum

这段代码可以在不同的上下文对象(peach和plum)中重复使用函数eat(),不用针对每个对象编写不同版本的函数。

情况一

看下面例子:

function fruit_shop() {console.log(this);
}
fruit_shop() // window
"use strict"
function fruit_shop() {
console.log(this);
}
fruit_shop() // undefined
function fruit_shop() {console.log(this);
}
(function () {"use strict";fruit_shop(); // window
})();
function fruit_shop_eat() {console.log(this);function eat_plum() {console.log(this);}eat_plum();
}
const fruit_shop = {name: "welcome to 1 of xiao wu fruit shop",
};
fruit_shop_eat.call(fruit_shop); // fruit_shop  window

小结

this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this就是这个记录的一个属性,会在函数执行的过程中用到。

将上面列子换成箭头函数在来看下结果

const fruit_shop = () => {console.log(this);
};
fruit_shop(); // window
"use strict"
const fruit_shop = () => {console.log(this);
};
fruit_shop(); // window
const fruit_shop = () => {console.log(this);
};
(() => {"use strict";fruit_shop(); // window
})();
const fruit_shop_eat = () => {console.log(this);const eat_plum = () => {console.log(this);};eat_plum();
};
const fruit_shop = {name: "welcome to 1 of xiao wu fruit shop",
};
fruit_shop_eat.call(fruit_shop); // window  window

额外的例子

const fruit_shop_eat = () => {console.log(this);return () => {console.log(this);};
};
const fruit_shop = {name: "welcome to 1 of xiao wu fruit shop",
};
const eat = fruit_shop_eat.call(fruit_shop); // window
eat(); //   window
function fruit_shop_eat() {console.log(this);return () => {console.log(this);};
}
const fruit_shop = {name: "welcome to 1 of xiao wu fruit shop",
};
const eat = fruit_shop_eat.call(fruit_shop); // fruit_shop
eat(); // fruit_shop

小结

ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。而是根据当前的词法作用域来决定this,具体来说,箭头函数会继承外层函数调用的this绑定(无论this绑定到什么)。这其实和ES6之前代码中的self = this机制一样。

情况二

看下面例子:

function eat() {console.log(this.name);
}
const peach = {name: "peach",eat,
};
peach.eat(); // peach

小结

调用位置会使用peach上下文来引用函数,当eat()被调用时,它的前面加上了对peach的引用。当函数引用有上下文对象时,会把函数调用中的this绑定到这个上下文对象。因此this.name和peach.name是一样的。

看下面例子:

function eat() {console.log(this.name);
}const peach = {name: "peach",eat,
};const fruit_shop = {name: "fruit shop",peach,
};
fruit_shop.peach.eat(); // peach

小结

对象属性引用链中只有上一层或者说最后一层在调用位置中起作用。

看下面例子:

function eat() {console.log(this);
}
const peach = {name: "peach",eat,
};
const eat_fresh = peach.eat;
eat_fresh(); // window
console.log(eat_fresh === eat); // true

小结

peach.eat和eat_fresh引用的是eat函数本身,eat_fresh不是一个对象属性。在非严格模式下指向window。

情况三

使用apply,bind,call方法

function fruit_shop() {console.log(this); 
}
const fruit_shop_bind = fruit_shop.bind({});
fruit_shop_bind(); // {}
fruit_shop.apply({}); // {}
fruit_shop.call({}); // {}
const fruit_shop = () => {console.log(this);
};
const fruit_shop_bind = fruit_shop.bind({});
fruit_shop_bind(); // window
fruit_shop.apply({}); // window
fruit_shop.call({}); // window

小结
Function 实例的 apply() ,bind(),call()方法会以给定的 this 值。三种方法不适应于箭头函数(this 的值将保持为闭合词法上下文的值)。

情况四

看下以下例子:

function FruitShop() {this.peach = "peach"console.log(this);
}
new FruitShop(); // FruitShop
function FruitShop() {this.peach = "peach";
}    
console.log(new FruitShop().peach); // peach

小结

该情况需要清楚使用new关键字会发生什么:

  1. 创建一个空的简单 JavaScript 对象。为方便起见,我们称之为 newInstance。
  2. 如果构造函数的 prototype 属性是一个对象,则将 newInstance 的 [[Prototype]] 指向构造函数的 prototype 属性,否则 newInstance 将保持为一个普通对象,其 [[Prototype]] 为 Object.prototype。
  3. 使用给定参数执行构造函数,并将 newInstance 绑定为 this 的上下文(换句话说,在构造函数中的所有 this 引用都指向 newInstance)。
  4. 如果构造函数返回非原始值,则该返回值成为整个 new 表达式的结果。否则,如果构造函数未返回任何值或返回了一个原始值,则返回 newInstance。(通常构造函数不返回值,但可以选择返回值,以覆盖正常的对象创建过程。)

总结

以上是我个人实践的总结,难免有疏漏或偏差之处,诚邀各位在评论区不吝赐教,让我们一起在交流中学习成长。

主要文献

  1. 《JavaScript高级程序设计(第4版)》;
  2. 《JavaScript语法简明手册》;
  3. 《你不知道的JavaScript(上卷)》 ;
  4. mdn web docs - this
  5. mdn web docs - new
  6. mdn web docs - apply
  7. mdn web docs - bind
  8. mdn web docs - call

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

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

相关文章

探索未来制造,BFT Robotics引领潮流

“买机器人&#xff0c;上BFT” 在这个快速变化的时代&#xff0c;创新和效率是企业发展的关键。BFT Robotics&#xff0c;作为您值得信赖的合作伙伴&#xff0c;专注于为您提供一站式的机器人采购和自动化解决方案。 产品系列&#xff1a; 协作机器人&#xff1a;安全、灵活、…

油封包装的关键注意事项

油封是各种机械系统中不可或缺的部件&#xff0c;防止泄漏和污染。通过正确的包装措施来确保其质量对于其性能和寿命至关重要。本文提供了有效油封包装所需的综合注意事项。 1、选择合适的包装材料 选择合适的包装材料是第一步。材料应能够保护油封免受物理损坏、环境污染和化…

如何进行socket 长连接稳定性测试

进行Socket长连接稳定性测试时&#xff0c;需要关注多个方面以确保连接的稳定性和可靠性。以下是一些关键的测试步骤和考虑因素&#xff1a; 确保连接建立和断开正常&#xff1a; 验证Socket连接能否正确建立&#xff0c;包括处理任何潜在的连接超时或认证问题。 检查断开连接…

Linux C语言:指针和指针变量

一、指针的作用 使程序简洁、紧凑、高效有效地表示复杂的数据结构动态分配内存能直接访问硬件能够方便的处理字符串得到多于一个的函数返回值 二、内存、地址和变量 1、内存地址 2、变量和地址 1&#xff09;变量用来在程序中保存数据 比如: int k 58; //声明一个int变…

基于JSP技术的社区疫情防控管理信息系统

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;JSP 数据库&#xff1a;MySQL 技术&#xff1a;JSPJavaBeans 工具&#xff1a;MyEclipse、Tomcat、Navicat 系统展示 首页 用户注册与登录界…

2024-5-7 石群电路-26

2024-6-7&#xff0c;星期五&#xff0c;15:00&#xff0c;天气&#xff1a;阴转小雨&#xff0c;心情&#xff1a;晴。今天虽然是阴雨天&#xff0c;但是心情不能差哦&#xff0c;离答辩越来越近了&#xff0c;今天学完习好好准备准备ppt&#xff0c;加油学习喽~ 今日观看了石…

Faster R-CNN:端到端的目标检测网络

本文回顾了由微软研究人员开发的 Faster R-CNN 模型。Faster R-CNN 是一种用于物体检测的深度卷积网络&#xff0c;在用户看来&#xff0c;它是一个单一的、端到端的统一网络。该网络可以准确快速地预测不同物体的位置。为了真正理解 Faster R-CNN&#xff0c;我们还必须快速概…

《接口自动化测试框架》代码片段 - 接口请求封装

抛砖引玉 requests模块是Python中发送HTTP请求的强大工具&#xff0c;它以其直观易用的API和人性化的设计赢得了广泛赞誉。 这个模块不仅提供了丰富的功能来定制HTTP请求&#xff0c;如设置请求头、传递URL参数等&#xff0c;还能够自动处理许多底层细节&#xff0c;如Cookie管…

重庆公司记账代理,打造专业财务管理解决方案的领先企业

重庆公司记账代理&#xff0c;作为专业的财务管理服务提供商&#xff0c;我们的目标是为公司的经营管理和决策提供科学、准确的财务数据支持&#xff0c;我们通过长期的专业经验和对市场的深入理解&#xff0c;为您提供一站式的记账服务和财务咨询。 专业团队 我们拥有一支由经…

如何移动 hiberfil.sys 文件来减少C盘空间

如何移动 hiberfil.sys 文件来减少C盘空间 hiberfil.sys 文件是什么&#xff1f; hiberfil.sys 文件是 Windows 系统在开启休眠功能后自动生成的内存镜像文件。这个文件保存了系统休眠时的内存内容&#xff0c;以便我们唤醒电脑之后可以快速恢复到休眠前的状态。这个文件通常…

基于JSP技术的师生交流平台

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;Myeclipse、B/S架构 系统展示 首页 管理员登录界面 学生信息管理…

Qwen2开源发布,各方位全面升级!

今天&#xff0c;通义千问团队带来了Qwen2系列模型&#xff0c;Qwen2系列模型是Qwen1.5系列模型的重大升级。包括了&#xff1a; 5个尺⼨的预训练和指令微调模型, 包括Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B、Qwen2-57B-A14B以及Qwen2-72B&#xff1b; 在中⽂英语的基础上&#xf…

Thermal-BST自动化工具在Flotherm建模中的应用与优势

引言 随着科技的不断发展&#xff0c;电子领域的需求也越来越广泛和多样化。然而&#xff0c;PCB板及其上的器件建模问题一直是电子工程师在设计过程中面临的重要挑战之一。软件中原有的PCB建模工具&#xff0c;转换出来的模型复杂&#xff0c;影响后期的网格划分&#xff0c;…

选择云桌面必看:影响云桌面性能的一些重要因素

当云桌面发展的如火如荼并被越来越多的人所追捧的时候&#xff0c;偶然在网上看到有人评论说云桌面太坑&#xff0c;说好的免维护和节省成本好像与想象中的还是不一样。云桌面真的太坑&#xff1f;那是因为你没做好这几点。 选择云桌面你该关注哪些指标&#xff1f; 其实从云…

查询SQL03:大的国家

问题描述 如果一个国家满足下述两个条件之一&#xff0c;则认为该国是 大国 &#xff1a; 面积至少为 300 万平方公里&#xff08;即&#xff0c;3000000 km2&#xff09;&#xff0c;或者 人口至少为 2500 万&#xff08;即 25000000&#xff09; 编写解决方案找出 大国 的国…

在一个繁忙的都市中,每天早上,一位咖啡店的店员都会用微笑和问候迎接每一位顾客。她的友善不仅让顾客感到温暖,也营造了一个愉快的消费环境。

在这个多元纷呈的世界里&#xff0c;我们每个人都在寻求着一种特殊的温度&#xff0c;那就是认可度。它如同冬日里的一缕阳光&#xff0c;温暖着我们的心灵&#xff1b;它似夏夜里的一阵清风&#xff0c;吹散了我们心头的烦忧。然而&#xff0c;认可度并非一成不变&#xff0c;…

亚马逊测评自养号技术全攻略:一站式解决方案

在跨境电商这行&#xff0c;产品测评可是个大问题。如果你的商品销量少&#xff0c;评价也不多&#xff0c;那买家就很难注意到你的产品&#xff0c;更别提下单购买了。毕竟&#xff0c;大家都喜欢跟风买那些已经有很多人好评的产品&#xff0c;而不是冒险尝试一个全新的。 我们…

替代UCC28250抗干扰支持预偏置启动|支持半桥全桥|增强型驱动器

1. 产品特性(替代UCC28250) ➢ 支持预偏置启动 ➢ 死区时间可调的同步整流输出 ➢ 支持电压模控制和电流模控制 ➢ 支持源边控制和副边控制 ➢ 5V&#xff0c;精度3%电压输出 ➢ 软启动和打嗝恢复时间可调 ➢ 同步整流软启动阈值和时间可调 ➢ 斜坡补偿信号斜率可调 ➢…

2009年408真题解析

2009年408真题解析 【2009.1】为解决计算机主机与打印机之间速度不匹配问题&#xff0c;通常设置一个打印数据缓冲区&#xff0c;主机将要输出的数据依次写入该缓冲区&#xff0c;而打印机则依次从该缓冲区中取出数据。该缓冲区的逻辑结构应该是。 A.栈 B.队列 C.树 D.图 …

【单调栈讲解】

单调栈 考察单调栈。 我们需要维护一个递增的单调栈&#xff0c;同时要给下标入栈&#xff0c;而不是元素入栈。 给i位置入栈的时候&#xff0c;发现右指针i1位置元素一定小&#xff0c;而左指针i-1位置元素也一定小&#xff0c;所以当前i位置元素出栈对应的答案为&#xff0…