前端里的this指向问题
目录
1.代码输出结果
2.代码输出结果
3.代码输出结果
4.代码输出结果
5.代码输出结果
6.代码输出结果
7.代码输出结果
8.代码输出结果
9.代码输出结果
10.代码输出结果
11.代码输出结果
12.代码输出结果
13.代码输出结果
14.代码输出结果
总结
1.代码输出结果
function foo() {console.log( this.a );
}function doFoo() {foo();
}var obj = {a: 1,doFoo: doFoo
};var a = 2;
obj.doFoo()
输出结果为2,因为执行foo的是doFoo函数,函数默认执行window
但是如果doFoo函数里:
function doFoo() {// foo();console.log(this.a);//1}
输出的就是1,因为执行它的是obj对象,会隐式的把this指向obj对象
2.代码输出结果
var a = 10
var obj = {a: 20,say: () => {console.log(this.a)}
}
obj.say() //10 var anotherObj = { a: 30 }
obj.say.apply(anotherObj) //10
输出结果为10;10
apply或者bind通过绑定会指向里面的参数
但是这个是往外翻两层到window这层,所以都是最外层的a=10
如果换成普通函数的话就是20;30
3.代码输出结果
function a() {console.log(this);
}
a.call(null);
输出结果为window
call里面的参数如果是null或者undefined的话,this就会指向全局对象(浏览器里是window)
但是在严格模式情况下,参数是null输出的就是null;参数是undefined输出的是undefined
4.代码输出结果
var obj = { name: 'cuggz', fun: function(){ console.log(this.name); }
}
obj.fun() // cuggz
new obj.fun() // undefined
第二个new是取出了obj里的fun作为新的构造函数,所以里面没有name参数,结果为undefined
5.代码输出结果
var obj = {say: function() {var f1 = () => {console.log("1111", this);}f1();},pro: {getPro:() => {console.log(this);}}
}
var o = obj.say;
o();
obj.say();
obj.pro.getPro();
第一个:o=obj.say然后再调用o(),其实相当于是:
o=function() {var f1 = () => {console.log("1111", this);}f1();},
而且里面是箭头函数,翻第一层到f1,第二层到o,o是一个函数,它拥有this,与o平级的this就是window
第二个:obj.say() 翻第一层到f1,第二层到say,say平级的this就是obj
第三个:obj.pro.getPro()第一层翻到getPro,翻第二层到pro(注意对象是没有this 的!!只有函数有!),所以第二层直接翻到最外层,this就是window
对象不构成单独的作用域=>没有this
6.代码输出结果
var myObject = {foo: "bar",func: function() {var self = this;console.log(this.foo); console.log(self.foo); (function() {console.log(this.foo); console.log(self.foo); }());}
};
myObject.func();
func是myObject调用的,所以func里面的this是myObject,那么self也是
this.foo就是bar
self.foo也是bar
下面的函数被调用,里面作用域的this是func,所以它里面没有foo属性,输出undefined
然后最后一个self.foo,这块是一个闭包,里面函数可以调用外层函数的属性self.foo===bar
7.代码输出结果
window.number = 2;
var obj = {number: 3,db1: (function(){console.log(this);this.number *= 4;return function(){console.log(this);this.number *= 5;}})()
}
var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number); // 15
console.log(window.number); // 40
⚠️注意:obj.db1是个立即执行函数,它在obj对象定义完之后就会执行,然后返回后面的函数
所以在下面一系列调用函数之前就会有一次输出window,而且此时window上的number=8,在非严格模式下,自执行函数IIFE输出的this就是window
所以第一次先会输出一个window,此时这个函数变成了这样:
window.number = 2;
var obj = {number: 3,db1: function(){console.log(this);this.number *= 5;}
}
var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number); // 15
console.log(window.number); // 40
db1=obj.db1之后,db1如下:
db1=function(){console.log(this);this.number *= 5;}
打印这个this就是window(db1时函数不是对象),此时window . number=5*8=40
然后调用obj.db1(),this打印obj对象,obj.number=3*5=15
8.代码输出结果
var length = 10;
function fn() {console.log(this.length);
}var obj = {length: 5,method: function(fn) {fn();arguments[0]();}
};obj.method(fn, 1);
fn()这样调用只是一个普通函数,而不是作为对象的方法去调用,所以this是window,输出10
而arguments承接参数fn和1,但是这次相当于arguments(因为它是个类数组对象!)去调用方法,所以this指向arguments,而且它是伪数组有length,输出2
9.代码输出结果
var a = 1;
function printA(){console.log(this.a);
}
var obj={a:2,foo:printA,bar:function(){printA();}
}obj.foo(); // 2
obj.bar(); // 1
var foo = obj.foo;
foo(); // 1
obj.foo(),foo里的this指向obj;它跟上面的区别是:上面那个只是由obj穿参的,但是不是obj去调用的,只是函数进行到那里去调用了,不是对象调用的,而这个就是obj调用的,所以this是obj;
obj.bar(),现在printA函数就不是由obj对象调用而进行的了,所以printA函数里的this是全局对象,输出1;
var foo=obj.foo,那么foo相当于(foo是函数):
全局上的foo:printA,this是window,输出1
10.代码输出结果
var x = 3;
var y = 4;
var obj = {x: 1,y: 6,getX: function() {var x = 5;return function() {return this.x;}();},getY: function() {var y = 7;return this.y;}
}
console.log(obj.getX()) // 3
console.log(obj.getY()) // 6
第一个:又是一个立即执行函数,IIFE里面的this指向全局对象,所以x=3
第二个:调用对象是obj,this是obj的this,输出6
11.代码输出结果
var a = 10; var obt = { a: 20, fn: function(){ var a = 30; console.log(this.a)} }obt.fn(); // 20obt.fn.call(); // 10(obt.fn)(); // 20
obt.fn()调用者是obj,所以函数里的this是obj,输出obj的a,20
obt.fn.call(),call用来改变this,但是里面的参数为空(null),call里的参数为undefined或者null,this就是全局对象window,所以输出a为10
()的作用是改变运算顺序,所以这个跟第一个没什么区别,输出20
12.代码输出结果
function a(xx){this.x = xx;return this
};
var x = a(5);
var y = a(6);console.log(x.x) // undefined
console.log(y.x) // 6
x一开始相当于:
var x=function a(5){
this.x=5;
return this
}
没有对象调用这个函数,所以this.x说的是window.x=5,最后return this => window,返回的window又赋值回给var x了,所以最外层的window.x=window,x.x=undefined
顺序:
window.x=5
var x=window=>window.x=window
y一开始相当于:
var y=function a(6){
this.x=6;
return this
}
window上的x=6,返回window赋值给y
顺序:
window.x=6
window=y
输出y.x=6
13.代码输出结果
function foo(something){this.a = something
}var obj1 = {foo: foo
}var obj2 = {}obj1.foo(2);
console.log(obj1.a); // 2obj1.foo.call(obj2, 3);
console.log(obj2.a); // 3var bar = new obj1.foo(4)
console.log(obj1.a); // 2
console.log(bar.a); // 4
先是调用obj1.foo(2),obj1去调用的函数,所以obj1里的a是2,下面输出为2
然后obj1.foo.call(obj2,3),obj2上的a赋值为3
var bar=new obj1.foo(4)这是又new了一个,所以不会赋值之前的2,obj1上的a输出还是2
bar相当于:
var bar=function foo(){},注意new出来的比隐式绑定优先级高,所以里面的this是bar,bar的a就是4
14.代码输出结果
function foo(something){this.a = something
}var obj1 = {}var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a); // 2var baz = new bar(3);
console.log(obj1.a); // 2
console.log(baz.a); // 3
这一步相当于:
var bar=function foo(sm){
this.a=sm;(this是obj1)
},obj1上
bar(2)=> obj1.a=2
var baz= new bar(3),new出来的比bind绑定的优先级高,所以this是baz,baz上的a为3
总结
改变this指向的四种方式:
函数默认指向,this是window
对象调用函数,函数里的this指向对象
显示绑定:call、apply、bind绑定,有参数绑定参数,null或者undefined就是window
通过new绑定this
其中new>显示>对象调用>默认指向
箭头函数里的this是一开始就定义好的,与后来谁去调用没有关系,this会继承自定义时的外层作用域,而且对象不会创建作用域,所以往外翻的时候只能翻到函数上
就比如这张图,obj.say()第一层到f1函数,第二层到say函数,然后找与say函数平级的this
obj.pro.getPro()第一层到getPro函数,第二层到最外层window
还有一些特殊情况比如立即执行匿名函数IIFE,在非严格模式下this就是window
相关文章:
前端里的this指向问题
目录 1.代码输出结果 2.代码输出结果 3.代码输出结果 4.代码输出结果 5.代码输出结果 6.代码输出结果 7.代码输出结果 8.代码输出结果 9.代码输出结果 10.代码输出结果 11.代码输出结果 12.代码输出结果 13.代码输出结果 14.代码输出结果 总结 1.代码输出结果 f…...
deepseek与gpt,核心原理对比
DeepSeek与GPT作为AI大模型,在自然语言处理等领域展现出强大的能力,它们的核心原理对比主要体现在模型架构、训练策略、资源效率以及应用场景优化等方面。 一、模型架构 DeepSeek 混合专家(MoE)框架:DeepSeek采用了混合专家框架,其内部包含多个“专家”子模块,每个子模…...
提示工程实现数据质量评估
提示工程实现数据质量评估 我准备先查看数据集的基本信息和内容,从完整性、准确性、一致性等方面评价数据质量,再依据数据规模、质量和潜在价值等因素进行定价。 import pandas as pd# 读取文件 excel_file = pd.ExcelFile(/mnt/a-极速-脑筋-98.xls)# 获取所有表名 sheet_n…...
[NKU]C++基础课(二)--- externC、强制类型转换、类与对象、面向对象程序设计语言、对象创建和使用、类的定义、封装
一、extern "C" (没看懂) extern "C" 是 C 语言中的一个特性,用于在 C 代码中声明使用 C 语言链接的变量或函数。这样做的目的主要是为了实现 C 代码与 C 代码之间的互操作性。 C 支持函数重载,而 C 不支持&…...
黑马Redis详细笔记(实战篇---短信登录)
目录 一.短信登录 1.1 导入项目 1.2 Session 实现短信登录 1.3 集群的 Session 共享问题 1.4 基于 Redis 实现共享 Session 登录 一.短信登录 1.1 导入项目 数据库准备 -- 创建用户表 CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,phone …...
什么是计算机总线?
计算机总线 文章目录 计算机总线1、总线的分类2、总线的组成3、总线的工作原理4、总线的性能指标 计算机总线是计算机各功能部件之间进行信息传输的公共通道,就像城市中的交通干线,负责连接计算机系统的各个组成部分,实现它们之间的数据、地址…...
ASP.NET配置文件多种方式读取
ASP.NET Core项⽬默认的配置⽂件是appsettings.json,创建项⽬时就会⾃动⽣成这个⽂ 件,我们可以将⼀些配置信息存放在这个配置⽂件中,这样做的好处是当我们修改配置⽂件 时,不在需要重启应⽤,可以实现热更新。 {"…...
基于N-gram模型的中文文本分析系统设计与实现
前言 在数字化人文研究快速发展的背景下,中文古典文本的量化分析面临着独特的挑战。古典文献中繁简异体字共存、语义单元边界模糊、意象隐喻密集等特征,使得传统的词频统计方法难以准确捕捉其深层语言规律。现有文本分析工具多面向现代汉语设计ÿ…...
零基础购买阿里云服务器,XShell连接云服务器
目录 1.环境搭建方式 2. 使用云服务器 3.使用终端软件登录到Linux 4.使用XShell登录主机 5.连接失败的原因: 下一篇更新:Linux的基础指令以及如何Linux的环境搭建 1.环境搭建方式 主要有四种: 1.直接安装在物理机上,虽然Linux有图形化…...
成熟开发者需具备的能力
精业务 • 指深入理解和熟悉所开发软件的业务逻辑和需求。 • 开发者需要明确软件要解决的问题、面向的用户群体以及核心功能等。 • 精业务有助于开发者更好地设计系统架构、编写符合业务需求的代码,并能根据业务变化灵活调整开发计划。 懂原理 • 指掌握编程的基…...
深入解析PID控制算法:从理论到实践的完整指南
前言 大家好,今天我们介绍一下经典控制理论中的PID控制算法,并着重讲解该算法的编码实现,为实现后续的倒立摆样例内容做准备。 众所周知,掌握了 PID ,就相当于进入了控制工程的大门,也能为更高阶的控制理论…...
CNN手写数字识别1——模型搭建与数据准备
模型搭建 我们这次使用LeNet模型,LeNet是一个经典的卷积神经网络(Convolutional Neural Network, CNN)架构,最初由Yann LeCun等人在1998年提出,用于手写数字识别任务 创建一个文件model.py。实现以下代码。 源码 #…...
深度学习04 数据增强、调整学习率
目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换(如旋转、翻转、裁剪等)&am…...
Python 自然语言处理(NLP)和文本挖掘的常规操作过程
Python 自然语言处理(NLP)和文本挖掘 自然语言处理(NLP)和文本挖掘是数据科学中的重要领域,涉及对文本数据的分析和处理。Python 提供了丰富的库和工具,用于执行各种 NLP 和文本挖掘任务。以下是一些常见的…...
掌握SQLite_轻量级数据库的全面指南
1. 引言 1.1 SQLite简介 SQLite 是一个嵌入式关系型数据库管理系统,它不需要单独的服务器进程或系统配置。它的设计目标是简单、高效、可靠,适用于各种应用场景,尤其是移动设备和嵌入式系统。 1.2 为什么选择SQLite 轻量级:文件大小通常在几百KB到几MB之间。无服务器架构…...
PH热榜 | 2025-02-16
1. Cal.com Routing 标语:根据客户线索,系统会智能地自动安排约会。 介绍:告别繁琐的排期!Cal.com 推出了新的路由功能,能更智能地分配预约,让你的日程安排更顺畅。这项功能运用智能逻辑和深入的数据分析…...
数据库基本概念及基本使用
数据库基本概念 什么是数据库: 数据库特点: 常见的数据库软件: 不同的公司进行不同的实践,生成了不同的产品。 比如买汽车,汽车只是一个概念,你要买哪个牌子哪个型号的汽车,才是真正的汽车的一…...
gozero实现数据库MySQL单例模式连接
在 GoZero 框架中实现数据库的单例连接可以通过以下步骤来完成。GoZero 使用 gorm 作为默认的数据库操作框架,接下来我会展示一个简单的单例模式实现。 ### 1. 定义数据库连接的单例结构 首先,你需要定义一个数据库连接的结构体,并在初始化…...
CSS flex布局 列表单个元素点击 本行下插入详情独占一行
技术栈:Vue2 javaScript 简介 在实际开发过程中有遇到一个场景:一个list,每行个数固定,点击单个元素后,在当前行与下一行之间插入一行元素详情,便于更直观的查看到对应的数据详情。 这种情形,…...
无人机航迹规划: 梦境优化算法(Dream Optimization Algorithm,DOA)求解无人机路径规划MATLAB
一、梦境优化算法 梦境优化算法(Dream Optimization Algorithm,DOA)是一种新型的元启发式算法,其灵感来源于人类的梦境行为。该算法结合了基础记忆策略、遗忘和补充策略以及梦境共享策略,通过模拟人类梦境中的部分记忆…...
权限五张表
重点:权限五张表的设计 核心概念: 在权限管理系统中,经典的设计通常涉及五张表,分别是用户表、角色表、权限表、用户角色表和角色权限表。这五张表的设计可以有效地管理用户的权限,确保系统的安全性和灵活性。 用户&…...
Docker-数据卷
1.数据卷 容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题: 如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了࿱…...
在Linux系统下修改Docker的默认存储路径
在Linux系统下修改Docker的默认存储路径可以通过多种方法实现,下边是通过修改daemon.json文件方式实现 查看当前Docker存储路径 使用命令 docker info | grep "Docker Root Dir" 查看当前Docker的存储路径,默认为 /var/lib/docker 停止Docker…...
IT : 是工作還是嗜好? Delphi 30周年快乐!
又到2月14日了, 自从30多年前收到台湾宝蓝(Borland)公司一大包的3.5 磁盘片, 上面用黑色油性笔写着Delphi Beta开始, Delphi便和我的工作生涯有了密不可分的关系. 一年后Delphi大获成功, 自此对于使用Delphi的使用者来说2月14日也成了一个特殊的日子! 我清楚记得Delphi Beta使用…...
DeepPose
目录 摘要 Abstract DeepPose 算法框架 损失函数 创新点 局限性 训练过程 代码 总结 摘要 DeepPose是首个将CNN应用于姿态估计任务的模型。该模型在传统姿态估计方法的基础上,通过端到端的方式直接从图像中回归出人体关键点的二维坐标,避免了…...
[HarmonyOS]鸿蒙(添加服务卡片)推荐商品 修改卡片UI(内容)
什么是服务卡片 ? 鸿蒙系统中的服务卡片(Service Card)就是一种轻量级的应用展示形式,它可以让用户在不打开完整应用的情况下,快速访问应用内的特定功能或信息。以下是服务卡片的几个关键点: 轻量级&#…...
DeepSeek R1 本地部署和知识库搭建
一、本地部署 DeepSeek-R1,是幻方量化旗下AI公司深度求索(DeepSeek)研发的推理模型 。DeepSeek-R1采用强化学习进行后训练,旨在提升推理能力,尤其擅长数学、代码和自然语言推理等复杂任务 。 使用DeepSeek R1, 可以大大…...
领域驱动设计叕创新,平安保险申请DDD专利
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 见下图: 这个名字拼得妙:领域驱动设计模式。 是领域驱动设计?还是设计模式?还是领域驱动设计设计模式?和下面这个知乎文章的…...
团体程序设计天梯赛-练习集——L1-041 寻找250
前言 10分的题,主要的想法就一个,按这个想法可以出几个写法 L1-041 寻找250 对方不想和你说话,并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。 输入格式: 输入在一行中给出不知道多少个绝对值…...
动量突破均值回归策略
动量突破均值回归策略:量化交易中的双剑合璧 引言 在量化交易的世界中,动量策略和均值回归策略是两种经典且广泛应用的策略。动量策略基于“强者恒强”的理念,认为过去表现良好的资产在未来一段时间内仍会继续表现良好;而均值回…...
