一篇文章让你安排JavaScript的this指向问题

别再只改config了!YOLO/RT-DETR多通道输入实战:数据集结构、多卡训练与参数优先级避坑指南 本文详细解析了YOLO/RT-DETR模型在多通道输入(如8通道多光谱图像)中的实战应用,涵盖数据集结构优化、数据加载器改造、模型参数调优及多卡训练配置。针对常见的多通道输入报错问题,提供了系统的解决方案和性能优化技巧,帮助开发者高效实现非标准数据格式的适配与训练。 阅读详情

我这里有前端进阶架构vip学习资料,包含内容有:HTML、css3、JavaScript、Vue,移动端web开发,Ajax、jQuery、canvas、等多个知识点。需要获取这些内容的朋友可以私信回复我“前端”两个字领取

如果要问javascript中哪两个知识点容易混淆,作用域查询和this机制绝对名列前茅。前面章节已经详细介绍过作用域的知识。本章将介绍this机制。

this绑定规则

默认绑定

  • 全局环境下,this默认绑定到window
console.log(this === window); //true
复制代码
  • 函数独立调用时,this默认绑定到window
function foo(){
    console.log(this === window);
}
foo();//true
复制代码
  • 被嵌套的函数独立调用时,this默认绑定到window
var a = 0;
var obj = {
    a : 2,
    foo : function (){
        function test(){
            console.log(this);
        }
        test();
    }
}
obj.foo();
复制代码

上面代码虽然test()函数被嵌套在obj.foo()函数中,但test()函数是独立调用,而不是方法调用。所以this默认绑定到window

IIFE

IIFE立即执行函数实际是函数声明后立即调用执行,内部的this指向了window

var a = 0;
function foo(){
    (function test(){
        console.log(this.a);
    })()
};
var obj = {
    a : 2,
    foo:foo
}
obj.foo();//0
复制代码

等价于上例

var a = 0;
var obj = {
    a : 2,
    foo : function(){
        function test(){
            console.log(this.a);
        }
        test();
    }
}
obj.foo();//0
复制代码

闭包

类似地,test()函数是独立调用,而不是方法调用,所以this默认绑定到window

注意:函数共有4中调用方法

var a = 0;
function foo() {
    function test() {
        console.log(this.a);
    }
    test();
}
var obj = {
    a: 2;
    foo: foo
}
obj.foo();//0
复制代码

​ 由于闭包的this默认绑定到window对象,但又常常需要访问嵌套函数的this,所以常常在嵌套函数中使用var that = this,然后在闭包中使用that替代this,使用作用域查找的方法来找到嵌套函数的this值

var a = 0;
function foo(){
    var that = this;
    function test(){
        console.log(that.a);
    }
    return test;
};
var obj = {
    a : 2,
    foo:foo
}
obj.foo()();//2
复制代码

隐式绑定

​ 一般地,被直接对象所包含的函数调用,也被称为方法地调用,this隐式绑定到该直接对象

function foo(){
    console.log(this.a);
}
var obj1 = {
    a : 1;
    foo: foo,
    obj2 : {
        a:2,
        foo:foo
    }
}
//foo()函数的直接对象是obj1,this隐式绑定到obj1
obj1.foo();//1
//foo()函数的直接对象是obj2,this隐式绑定到obj2
obj1.obj2.foo();//2
复制代码

隐式丢失

​ 隐式丢失是指被隐式绑定的函数丢失绑定对象,从而默认绑定到window。这种情况容易出错却又常见

【函数别名】

var a = 0;
function foo(){
    console.log(this.a);
}
var obj = {
    a: 1,
    foo:foo
}
//把obj.foo赋予别名bar,造成了隐式丢失,因为只是把foo()函数赋给了bar,而bar与obj对象则毫无关系
var bar = obj.foo;
bar();//0
复制代码
//等价于
var a = 0;
var bar = function foo(){
    console.log(this.a);
}
bar();//0
复制代码

【参数传递】

var a = 0;

function foo() {
    console.log(this.a);
}

function bar(fn) {
    fn();
}
var obj = {
    a: 2,
    foo: foo
}
//把obj.foo当做参数传递给bar函数时,有隐式的函数赋值 fn = obj.foo,只是把foo函数赋给了fn,而fn与obj对象毫无关系
bar(obj.foo);//0
复制代码
//等价于
var a = 0;
function bar(fn){
    fn();
}
bar(function foo(){
    console.log(this.a);
})
复制代码

【内置函数】

内置函数与上例类似,也会造成隐式丢失

var a = 0;
function foo(){
    console.log(this.a);
}
var obj = {
    a : 2,
    foo:foo
}
setTimeout(obj.foo,100);//0
复制代码

【间接调用】

​ 函数的“间接引用”一般都在无意间创建,最容易在赋值时发生,会造成隐式丢失

function foo(){
    console.log(this.a);
}
var a = 2;
var o = {a: 3,foo: foo};
var p = {a: 4};
o.foo();//3;
//将o.foo函数赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即调用
(p.foo = o.foo)();//2
复制代码
//另一种情况
function foo() {
    console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
//将o.foo函数赋值给p.foo函数,之后p.foo函数再执行,是属于p对象的foo函数的执行
p.foo = o.foo;
p.foo();//4
复制代码

【其他情况】

​ 在javascript引擎内部,obj和obj.foo储存在两个内存地址,简称为M1和M2。只有obj.foo()这样调用时,是从M1调用M2,因此this指向obj。但是,下面三种情况,都是直接取出M2进行运算,然后就在全局环境执行运算结果(还是M2),因此this指向全局环境

var a = 0;
var obj = {
    a:2,
    foo:foo
}
function foo(){
    console.log(this.a);
}
(obj.foo = obj.foo)();//0
(false || obj.foo)();//0
(1,obj.foo)();//0
复制代码

显示绑定

​ 通过call()、apply()、bind()方法把对象绑定到this上,叫做显示绑定。对于被调用的函数来说,叫做间接调用

var a = 0;
function foo(){
    console.log(this.a);
}
var obj = {
    a : 2
};
foo();//0
foo.call(obj);//2
复制代码

​ 普通的显示绑定无法解决隐式丢失问题

var a = 0;
function foo(){
    console.log(this.a);
}
var obj1 = {
    a : 1
};
var obj2 = {
    a : 2
}
foo.call(obj1);//1
foo.call(obj2);//2
复制代码

【硬绑定】

​ 硬绑定是显式绑定的一个变种,使this不能再被修改

var a = 0;
function foo(){
    console.log(this.a);
}
var obj = {
    a:2
};
var bar = function (){
    foo.call(obj);
}
//在bar函数内部手动调用foo.call(obj)。因此,无论之后如何调用函数bar,它总会手动会在obj上调用foo
bar();//2
setTimeout(bar,2000);//2
bar.call(window);//2
复制代码

【API】

​ javascript中新增了许多内置函数,具有显式绑定的功能,如数组的5个迭代方法:map()、forEach()、filter()、some()、every()

var id = 'window';
function foo(el){
    console.log(el,this.id);
}
var obj = {
    id: 'fn'
};
[1,2,3].forEach(foo);//1 "window" 2 "window" 3 "window"
[1,2,3].forEach(foo,obj);//1 "fn" 2 "fn" 3 "fn"
复制代码

new绑定

​ 如果函数或者方法调用之前带有关键字new,它就构成构造函数调用。对于this绑定来说,称为new绑定

【1】构造函数通常不适用return关键字,他们通常初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值

function fn(){
    this.a = 2;
}
var test = new fn();
console.log(test);//{a:2}
复制代码

【2】如果构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果

function fn(){
    this.a = 2;
    return;
}
var test = new fn();
console.log(test);//{a:2}
复制代码

【3】使用构造函数显示地使用return语句返回一个对象,那么调用表达式的值就是这个对象

var obj = {a:1};
function fn(){
    this.a = 2;
    return obj;
}
var test = new fn();
console.log(test);//{a:1}
复制代码

注意:尽管有时候构造函数看起来像一个方法调用,它依然会使用这个新对象作为this。也就是说,在表达式new o.m()中,this并不是o

var o = {
    m:function(){
        return this;
    }
}
var obj = new o.m();
console.log(obj,obj === o);//{} false
console.log(obj.contructor === o.m);//true
复制代码

严格模式

【1】严格模式下,独立调用的函数的this指向undefined

function fn(){
    'use strict';
    console.log(this);//undefined
}
fn();

function fn(){
    console.log(this);//window
}
fn();
复制代码

【2】在非严格模式下,使用函数的call()或apply()方法时,null或undefined值会被转换成全局对象。而在严格模式下,函数的this值始终是指定的值

var color = 'red';
function displayColor(){
    console.log(this.color);
}
displayColor.call(null);//red

var color = 'red';
function displayColor(){
    'use strict';
    console.log(this.color);
}
displayColor.call(null);//TypeError: Cannot read property 'color' of null
复制代码

总结

  • this的四种绑定规则:默认绑定、隐式绑定、显式绑定和new绑定,分别对应函数的四种调用方式:独立调用、方法调用、间接调用和构造函数调用。
  • 分清这四种绑定规则不算难,但是比较麻烦的是需要练就火眼金睛,识别出隐式丢失的情况。
  • 说到底,JavaScript如此复杂的原因是因为函数过于强大。因为,函数是对象,所以原型链比较复杂;因为函数可以作为值被传递,所以执行环境栈比较复杂;同样地,因为函数具有多种调用方式,所以this的绑定规则也比较复杂
  • 只有理解了函数,才算理解javascript

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  1. 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  2. 私信后台回复【前端】有惊喜!
  3. 同时可以期待后续文章ing
从零到一:桌面宠物的硬件架构设计与工程实践 本文详细介绍了基于STM32F103C8T6主控平台的桌面宠物机器人硬件架构设计与工程实践。内容涵盖电源管理、舵机控制、PCB布局及系统调试等核心环节,为硬件爱好者提供从零到一的完整开发指南,助力打造稳定可靠的智能桌面伴侣。 阅读详情

相关推荐

uniapp+华为HBuilder X 4.29跑鸿蒙模拟器报错没有签名授权

uniapp+华为HBuilder X 4.29跑鸿蒙模拟器报错没有签名授权报错信息11:39:47.976 安装 .hap 到鸿蒙设备 ...11:39:48.517 运行所需的权限没有签名授权,请参考 配置文档11:39:48.517 安装失败。

weixin_66071584的博客 1350

JavaScript中的this指向问题

JavaScript中的this指向问题 文章目录JavaScript中的this指向问题**1、什么是this****2、用来干嘛****3、怎么在代码中使用****4、改变this指向**4.1引入call、bind、apply**4.1.1区别**4.1.2怎么用 1、什么是this this一般指向的是调用它的对象,比如调用它的上下文是window对象,那就是指向window对象,如果调用它的上下文是某对象就是指向某对象…… //例如 <script> console.log(thi

DevelopmentStack的博客 331

Verilog流水线CPU设计(超详细)

快把这一篇给更了

Ace Cheney的博客 7万+

Nodejs 中关于 this 的使用以及与浏览器 JavaScript 中的 this 的区别【亲自踩坑总结,值得收藏】

前言 最近根据安排,在参与一个自动化测试工具的开发,本项目是基于 Nodejs 开发的,由于挺长时间没有使用 Nodejs 进行完整的项目开发了,所以在开发过程中还会踩不少坑,所以这就来了。 我们这里说的是在 Nodejs 中的 this,而不是在 JavaScript 中的 this。Nodejs 中的 this 和在浏览器中 JavaScript 中的 this 还是不一样的,所以大家还是需要区分一下。(关于 Nodejs 中的 this 与 Javascript 中的 this 的区别,在文末我也替大

XH_jing的博客 1012

零基础学simulink仿真建模--基于Simulink进行农业机械用开关磁阻电机的仿真建模

特点结构简单:无电刷、换向器等易损件,维护成本低。坚固耐用:适合恶劣的工作环境,如农业机械作业现场。宽调速范围:通过适当的控制策略可以实现较宽的速度调节范围。挑战非线性特性:SRM的电磁特性和转矩特性具有高度非线性。复杂性:涉及电气、机械动力学以及控制系统的设计与集成。实时性要求:需要快速响应以适应不断变化的操作条件。多变量优化:包括电流控制、速度控制等多个方面需综合考虑。使用Simscape Electrical库来构建一个开关磁阻电机模型。

amy_mhd的博客 909

如何用Hugo Stack主题打造极简技术博客?3个必改配置与5个高级美化技巧

本文详细解析了如何深度定制Hugo Stack主题,打造个性化技术博客。文章提供了3个必改配置与5个高级美化技巧,涵盖字体美学、布局重构、代码块视觉强化及细节打磨,帮助开发者超越基础部署,实现从功能到美学的进阶,提升博客质感与用户体验。

carrot的博客 568

JavaScript问题总结

JavaScript问题

杨思默 507

5步搞定ABB机器人RobotStudio与S7-1500PLC的Profinet通讯(附PLCSIM调试技巧)

本文详细介绍了如何利用RobotStudio与TIA Portal软件,结合PLCSIM Advanced仿真器,在零硬件条件下实现ABB机器人与西门子S7-1500 PLC之间的Profinet通讯虚拟调试。通过五个核心步骤,从环境搭建、网络配置、信号映射到联合仿真与高级调试,帮助工程师在项目前期高效验证逻辑、压缩现场调试周期,并掌握实用的PLCSIM调试技巧。

weixin_29188043的博客 505

JavaScript中递归,深拷贝,异常处理,改变this的指向

JavaScript中递归,深拷贝,异常处理,改变this的指向

m0_62371650的博客 309

安防相机宽动态(WDR)技术解析:从原理到实战应用

本文深入解析安防相机宽动态(WDR)技术原理,对比多次曝光与DOL-WDR等实现方式,并区分硬件WDR与数字WDR(DWDR)的本质差异。文章重点阐述了WDR在逆光出入口、夜间道路监控等五大典型场景的实战应用与调参技巧,旨在帮助用户根据实际需求正确选择与配置,确保监控系统在复杂光线下清晰成像。

weixin_29191081的博客 428

001-基础入门-Web演示源码&资源&工具箱等

小迪安全2023笔记

wushangyu32335的博客 4263

js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

壹 ❀ 引 可以说this与闭包、原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地。可开发好几年,被几道this题安排明明白白的人应该不在少数(我就是其一)。我觉得this概念抽象,变化多端总是让人晕头转向,但平心它并不是有多难,今天我们就从this绑定的五种场景(默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定)出发,静下心来好好聊聊这个 this,本文开始。 贰 ❀ this默认绑定 this默认绑定我们可以理解为函数调用时无任何调用前缀的情.

FREEDOM 1180

华为OD机考双机位C卷 - 员工派遣 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 员工派遣 (OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 1035

中max函数_浅析Js中call,apply,bind

前言了解this的指向(文章中的调用方法与this息息相关)了解过函数调用了解过call()、apply()、bind()迦南:深入理解JS中this(一)​zhuanlan.zhihu.com迦南:深入理解JS中this(二)​zhuanlan.zhihu.com目录:call、apply、bind 的区别分别是什么?call、apply、bind 的用法分别是什么?call、apply、bin...

weixin_35589806的博客 364

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2006A每日任务安排

vue组件通信(父传子,子传父,兄弟组件通信) vue生命周期 (单词,每个钩子函数可以做什么,执行顺序)

田兴的博客 1654

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

JavaScript之闭包

点击查看所有文章目录 点击查看 JavaScript作用域、闭包、this指向系列文章目录 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 要理解闭包,首先必须理解JS作用域[点击查看] 闭包的概念 在百度百科上是这么解释闭包的: 其实这个说法是很笼统的。准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用...

qq_42911663的博客 443

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

(计算机毕设选题推荐)基于SpringBoot和Vue.js的在线教室安排系统

本文设计并实现了一个基于SpringBoot和Vue.js的在线教室安排系统,旨在提高学校教室资源的管理效率和利用率。该系统采用前后端分离架构,前端使用Vue.js框架进行开发,提供友好的用户界面和交互体验;后端采用SpringBoot框架,结合MySQL数据库,实现业务逻辑和数据存储。系统主要功能模块包括角色管理、课程档案管理、教室资源管理、排课申请与审批等。通过该系统,教务管理员可以方便地管理教室资源,教师可以根据实际需求提交排课申请,系统还能自动进行排课冲突检测和教室资源优化分配。

机器学习硕博工作室(计算机毕设)的博客 934

Day4 JavaScript 复习打卡

JS高级学习: 函数 1.this的指向问题: 2.call,apply,bind 函数方法 call:可以调用函数,可以改变函数中this的指向 第一个参数:要改变this指向的参数 第二个参数及后面参数:其他参数列表 apply:同call,不同点就是传参列表是数组的样式 bind:不可以调用函数,会把函数作为返回值,可以多次调用。其他同call 三者的区别: 三者都可以改变函数中this的指向 call,apply都可以调用函数,不同之处就是两者的传参方式不同,call是fu

weixin_49267522的博客 1074

web workers_如何使用Web Workers在JavaScript中安排一致的异步任务

web workersby Danny Mcwaves 丹尼·麦克维斯(Danny Mcwaves) 如何使用Web Workers在JavaScript中安排一致的异步任务 (How to use Web Workers to schedule consistent asynchronous tasks in JavaScript) With the continuous improveme...

cumian9828的博客 195

JavaScript的小小总结!变量类型、对象声明、this用法、原型、匿名函数、闭包和自执行函数

一件任务的完成,意味着另外任务的开始,工作就这样,周而复始,就像春夏秋冬一样,四季轮回,其实工作是做不完的,上一个工作任务也许并没有完成,而下一个任务已经有了安排,写代码,搞程序,其实里面有很多东西是不可控制的,一个问题,一个似乎觉得微不足道的问题,可能让人绞尽脑汁,没有源码的帮助,如果是单纯的二次开发,有的时候真不知道问题出在什么地方,我这一段时间就被一个乱码问题折腾的要死,各种编码尝试都不见效

一亩地的专栏 660

大白话JavaScript结合具体代码场景,剖析this关键字的取值规则

关键字就像是个调皮的小精灵,它的值会随着不同的情况变来变去,就像川剧变脸一样。这调皮鬼在全局作用域和普通函数调用时指向全局对象,在方法调用时指向调用方法的对象,在构造函数调用时指向新创建的对象,在。关键字的取值取决于调用该方法的对象。在对象的方法里时,它就像个忠诚的小跟班,指向调用这个方法的对象。关键字会指向调用该方法的对象。// 在事件处理函数中,this 指向触发事件的元素,即按钮元素。就像个新生宝宝的专属保姆,指向新创建的对象。指向触发该事件的元素,也就是按钮元素。对象的方法调用,在非严格模式下,

前端大白话 959

js中的闭包

闭包的本质就是在一个函数的内部创造另一个函数,我们可以在一个函数的内部也有权访问另一个函数内部的变量。 闭包的三个特性: 1.函数嵌套函数; 2.函数内部可以引用函数外部的参数和变量; 3.参数和变量不会被垃圾回收机制收回。 闭包的两种形式: 1.函数作为返回值 function a(){ var name='dov'; return function (){ ...

weixin_38098192的博客 199

5种JavaScript的绑定,帮你彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定...

来源 | https://www.cnblogs.com/echoyya/p/14506742.html可以说this与闭包、原型链一样,属于JavaScript开发中老生常谈的问题了,百...

web前端开发 545

JavaScript设计模式与开发事件阅读总结(一)

JavaScript设计模式与开发事件阅读总结(一) 面向接口编程 多态 封装 设计模式———原型模式 this指向 call和apply的同异 Function.prototype.bind()方法 闭包 命令模式 高阶函数

cloki的博客 420

js 五种绑定this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

壹 ❀ 引 可以说this与闭包、原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地。可开发好几年,被几道this题安排明明白白的人应该不在少数(我就是其一)。我觉得this概念抽象,变化多端总是让人晕头转向,但平心它并不是有多难,今天我们就从this绑定的五种场景(默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定)出发,静下心来好好聊聊这个 this,本文开始。 贰 ❀ this默认绑定 this默认绑定我们可以理解为函数调用时无任何调用前缀的情景

前端菜菜DayDayUp的博客 951

2026 JavaScript全套零基础教程:从语法到项目实战的完整学习路线

系统化的前端学习路径是初学者快速入门的关键。JavaScript 作为前端开发的核心语言,其语法基础、函数、DOM 操作、异步编程等知识点的掌握顺序直接影响学习效率。一套完整的零基础教程不仅涵盖从变量、数据类型到 ES6+ 的语法进阶,还通过前后端分离项目实战串联核心概念,帮助学习者建立工程化思维。合理的学习路线能显著降低入门门槛,适用于转行前端、校招面试准备以及 Vue/React 框架基础巩固等场景。通过本地环境搭建、源码对照练习和常见报错排查,学习者可以逐步构建可迁移的编程能力,最终具备独立开发与面试

weixin_32247165的博客 290
上一篇: Java之父推荐,终于学完了阿里P8推荐的Java性能优化文档
下一篇: js性能优化:彻底弄懂函数防抖和函数节流
Javaesandyou
博客等级 码龄5年 742粉丝 563原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值