前端里的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

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

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

相关文章

苹果CMS新版站群管理更新_新增批量生成插件优势何在

引言 随着互联网的发展,站群管理成为了网站运营者提升流量和SEO效果的重要策略。苹果CMS新版站群管理系统通过引入批量生成插件,为用户提供了更高效、更智能的解决方案。本文将详细介绍这一更新的功能特点及其优势。 站群管理功能特点 多域名独立配置…

时序约束进阶八:时钟抖动Jitter与不确定性Uncertainty

目录 一、前言 二、时钟抖动 2.1 时钟抖动类型 2.2 set_input_jitter 2.3 set_system_jitter 2.4 set_clock_uncertainty 2.5 设计代码 2.6 约束解析 2.7 Input_jitter报告 2.8 System Jitter报告 2.9 Clock Uncertainty报告 2.9.1 Uncertainty的计算 2.9.2 Uncer…

小米 R3G 路由器(Pandavan)实现网络打印机功能

小米 R3G 路由器(Pandavan)实现网络打印机功能 一、前言 家中有多台 PC 设备需要打印服务,但苦于家中的 Epson L380 打印机没有网络打印功能,并且配置 Windows 共享打印机实在是过于繁琐且需要共享机保持唤醒状态过于费电。想到…

Leetcode Hot100 第30题 416.分割等和子集

class Solution { public:bool canPartition(vector<int>& nums) {int sum0;for(int num:nums){sumnum;}if(sum%21) return false;int bag_size sum/2;// return dfs(nums,nums.size()-1,bag_size);//递归做法vector<vector<bool>> dp(nums.size()1,vec…

技术晋升读书笔记—阿里管理三板斧(二)

一、引子 美团王兴问马云&#xff1a;“你最强的地方是什么&#xff1f;” 马云反问王兴&#xff1a;“你觉得呢&#xff1f;” 王兴回答&#xff1a;“战略和忽悠。” 马云哈哈大笑&#xff0c;笑完&#xff0c;他一本正经地说&#xff1a;“我最强的地方是管理。” &quo…

引入了 Disruptor 后,系统性能大幅提升!

Disruptor 是一个很受欢迎的内存消息队列&#xff0c;它源于 LMAX 对并发、性能和非阻塞算法的研究。今天一起来学习一下这个消息队列。 简介 对于主流的分布式消息队列来说&#xff0c;一般会包含 Producer、Broker、Consumer、注册中心等模块。比如 RocketMQ 架构如下&…

【WPSOffice】汇总

写在前面 PPT篇 幻灯片母版 通过母版功能统一幻灯片的样式、字体、颜色等&#xff0c;提高整体一致性。 统一设置模板样式 字体安装 查找到字体并安装。 在WPS PPT&#xff08;WPS演示&#xff09;中&#xff0c;以下是最常用的十个功能&#xff0c;能够帮助用户高效制作…

鸿蒙开发:熟知@BuilderParam装饰器

前言 本文代码案例基于Api13。 在实际的开发中&#xff0c;我们经常会遇到自定义组件的情况&#xff0c;比如通用的列表组件&#xff0c;选项卡组件等等&#xff0c;由于使用方的样式不一&#xff0c;子组件是动态变化的&#xff0c;针对这一情况&#xff0c;就不得不让使用方把…

在Nodejs中使用kafka(一)安装使用

安装 方法一、使用docker-compose安装 1、创建docker-compose.yml文件。 services:zookeeper:image: docker.io/bitnami/zookeeper:3.9ports:- "2181:2181"volumes:- "./data/zookeeper:/bitnami"environment:- ALLOW_ANONYMOUS_LOGINyeskafka:image: …

CRISPR spacers数据库;CRT和PILER-CR用于MAGs的spacers搜索

iPHoP&#xff1a;病毒宿主预测-CSDN博客 之前介绍了这个方法来预测病毒宿主&#xff0c;今天来介绍另一种比较用的多的方法CRISPR比对 CRISPR spacers数据库 Dash 在这可以下载作者搜集的spacers用于后期比对 CRT和PILER-CR 使用 CRT 和 PILERCR 识别 CRISPR 间隔区&#x…

深入理解Java的 JIT(即时编译器)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

LabVIEW开发CANopen紧急对象读取

本示例展示了如何通过CANopen协议读取设备的紧急对象&#xff08;Emergency object&#xff09;。紧急对象用于报告设备发生故障或异常情况时的紧急信息。通过该示例&#xff0c;用户可以配置并读取设备发送的紧急消息&#xff0c;确保在设备发生紧急状况时能够及时响应。 主要…

DeepSeek官方推荐的AI集成系统

DeepSeek模型虽然强大先进&#xff0c;但是模型相当于大脑&#xff0c;再聪明的大脑如果没有输入输出以及执行工具也白搭&#xff0c;所以需要有配套工具才能让模型发挥最大的作用。下面是一个典型AI Agent架构图&#xff0c;包含核心组件与数据流转关系&#xff1a; #mermaid-…

【第13章:自监督学习与少样本学习—13.4 自监督学习与少样本学习的未来研究方向与挑战】

凌晨三点的实验室里,博士生小张盯着屏幕上的训练曲线——他设计的跨模态少样本学习模型在医疗影像诊断任务上突然出现了诡异的性能断崖。前一秒还在92%的准确率高位运行,下一秒就暴跌到47%。这个看似灾难性的现象,却意外揭开了自监督学习与少样本学习技术深藏的核心挑战… 一…

论文解读之DeepSeek R1

今天带来DeepSeek R1的解读 一、介绍 deepseek主打复杂推理任务&#xff0c;如数学、代码任务。 R1以预训练过的V1-base初始化&#xff0c;主要发挥了RL在长思维链上的优势&#xff0c;R1-Zero直接RL而在前置步骤中不进行SFT&#xff0c;即缺少了有监督的指令微调阶段&#…

【Java学习】类和对象

目录 一、选择取块解 二、类变量 三、似复刻变量 四、类变量的指向对象 五、变量的解引用访问 1.new 类变量(参) 2.this(参) 3.类变量/似复刻变量. 六、代码块 七、复制变量的赋值顺序 八、访问限定符 1.private 2.default 九、导类 一、选择取块解 解引用都有可以…

使用css实现镂空效果

前言&#xff1a; 最近在公司完成小程序的新手引导中遇到了要将蒙层挖空&#xff0c;漏出后面内容的功能&#xff0c;找了各种资料之后&#xff0c;发现了一种就使用几行css代码就实现这个效果的方式&#xff0c;在这里分享给各位小伙伴们。 功能描述&#xff1a;实现下图的镂…

15.1 Process(进程)类

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 通常开发时想要获得进程是比较困难的事&#xff0c;必须要调用CreateToolhelpSnapshot、ProcessFirst、ProcessNext等API或者诸如 Zw…

【全栈开发】----Mysql基本配置与使用

本篇是在已下载Mysql的情况下进行的&#xff0c;若还未下载或未创建Mysql服务&#xff0c;请转到这篇: 2024 年 MySQL 8.0.40 安装配置、Workbench汉化教程最简易&#xff08;保姆级&#xff09;_mysql8.0.40下载安装教程-CSDN博客 本文对于mysql的操作均使用控制台sql原生代码…

数据恢复-01-机械硬盘的物理与逻辑结构

磁盘存储原理 磁盘存储数据的原理&#xff1a; 磁盘存储数据的原理是利用磁性材料在磁场作用下的磁化性质&#xff0c;通过在磁盘表面上划分成许多小区域&#xff0c;根据不同的磁化方向来表示0和1的二进制数据&#xff0c;通过读写磁头在磁盘上的移动&#xff0c;可以实现数据…