Javascript 中的this指向

news/2025/2/28 7:27:11/

前言

JavaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。

this的指向

除去不常用的with和eval的情况,具体到实际应用中,this的指向大致可以分为以下4种。

❏ 作为对象的方法调用。

❏ 作为普通函数调用。

❏ 构造器调用。

❏ Function.prototype.call或Function.prototype.apply调用。

下面我们分别进行介绍。

1.作为对象的方法调用

当函数作为对象的方法被调用时,this指向该对象:

        var obj = {a: 1,getA: function(){alert ( this === obj );    // 输出:truealert ( this.a );    // 输出: 1}};obj.getA();

2.作为普通函数调用

当函数不作为对象的属性被调用时,也就是我们常说的普通函数方式,此时的this总是指向全局对象。在浏览器的JavaScript里,这个全局对象是window对象。

        window.name = 'globalName';var getName = function(){return this.name;};console.log( getName() );    // 输出:globalName

或者:

        window.name = 'globalName';var myObject = {name: 'sven',getName: function(){return this.name;}};var getName = myObject.getName;console.log( getName() );    // globalName

有时候我们会遇到一些困扰,比如在div节点的事件函数内部,有一个局部的callback方法,callback被作为普通函数调用时,callback内部的this指向了window,但我们往往是想让它指向该div节点,见如下代码:

        <html><body><div id="div1">我是一个div</div></body><script>window.id = 'window';document.getElementById( 'div1' ).onclick = function(){alert ( this.id );        // 输出:'div1'var callback = function(){alert ( this.id );        // 输出:'window'}callback();};</script></html>

此时有一种简单的解决方案,可以用一个变量保存div节点的引用:

        function func(){"use strict"alert ( this );    // 输出:undefined}func();

在ECMAScript 5的strict模式下,这种情况下的this已经被规定为不会指向全局对象,而是undefined:

        function func(){"use strict"alert ( this );    // 输出:undefined}func();

3.构造器调用

JavaScript中没有类,但是可以从构造器中创建对象,同时也提供了new运算符,使得构造器看起来更像一个类。

除了宿主提供的一些内置函数,大部分JavaScript函数都可以当作构造器使用。构造器的外表跟普通函数一模一样,它们的区别在于被调用的方式。当用new运算符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的this就指向返回的这个对象,见如下代码:

        var MyClass = function(){this.name = 'sven';};var obj = new MyClass();alert ( obj.name );     // 输出:sven

但用new调用构造器时,还要注意一个问题,如果构造器显式地返回了一个object类型的对象,那么此次运算结果最终会返回这个对象,而不是我们之前期待的this:

        var MyClass = function(){this.name = 'sven';return {    // 显式地返回一个对象name: 'anne'}};var obj = new MyClass();alert ( obj.name );     // 输出:anne

如果构造器不显式地返回任何数据,或者是返回一个非对象类型的数据,就不会造成上述问题:

        var MyClass = function(){this.name = 'sven'return 'anne';    // 返回string类型};var obj = new MyClass();alert ( obj.name );     // 输出:sven

4. Function.prototype.call或Function.prototype.apply调用

跟普通的函数调用相比,用Function.prototype.call或Function.prototype.apply可以动态地改变传入函数的this:

        var obj1 = {name: 'sven',getName: function(){return this.name;}};var obj2 = {name: 'anne'};console.log( obj1.getName() );     // 输出: svenconsole.log( obj1.getName.call( obj2 ) );    // 输出:anne

call和apply方法能很好地体现JavaScript的函数式语言特性,在JavaScript中,几乎每一次编写函数式语言风格的代码,都离不开call和apply。在JavaScript诸多版本的设计模式中,也用到了call和apply。


http://www.ppmy.cn/news/13150.html

相关文章

【Leetcode】面试题 01.02. 判定是否互为字符重排、面试题 01.04. 回文排列

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 面试题 01.02. 判定是否互为字符重排 面试题 01.04. 回文排列 面试题 …

SpringBoot自动配置原理

SpringBoot自动配置原理starter介绍starter原理2.1 起步依赖2.2 自动配置2.2.1 基于Java代码的Bean配置2.2.2 自动配置条件依赖2.2.3 Bean参数获取2.2.4 Bean的发现starter介绍 spring boot 在配置上相比spring要简单许多, 其核心在于spring-boot-starter, 在使用spring boot来…

【MySQL Shell】第 9 章 MySQL InnoDB ReplicaSet

本章目录 9.1 部署 InnoDB ReplicaSet 9.2 配置 InnoDB ReplicaSet 实例 9.3 创建 InnoDB ReplicaSet 9.4 向 ReplicaSet 添加实例 9.5 采用一个现有的复制设置 9.6 更改主实例 9.7 强制一个新的主实例 9.8 InnoDB ReplicaSet 锁 9.9 标记 ReplicaSets 9.10 检查 InnoDB Repli…

【每日一道智力题】之 轮流取石子(简单的尼姆博弈)

题目&#xff1a;一共有N颗石子&#xff08;或者其他乱七八糟的东西&#xff09;&#xff0c;每次最多取M颗最少取1颗&#xff0c;A&#xff0c;B轮流取&#xff0c;谁最后会获胜&#xff1f;&#xff08;假设他们每次都取最优解&#xff09;。解答&#xff1a;结论&#xff1a…

《后端技术面试 38 讲》学习笔记 Day 14

《后端技术面试 38 讲》学习笔记 Day 14 34 | 技术修炼之道&#xff1a;同样工作十几年&#xff0c;为什么有的人成为大厂架构师&#xff0c;有的人失业&#xff1f; 原文摘抄 最近几年的时间他承担的工作职责几乎没有变化&#xff0c;使用的技术、开发的项目几乎和头几年一样…

盘点:2022年豆瓣评分8.0以上的计算机书籍有哪些?

2022年已经结束 &#xff0c;小编来盘点一下过去一年里出版的计算机图书里&#xff0c;有哪些计算机书籍是豆瓣评分8.0以上图书。 1、人工智能&#xff1a;现代方法&#xff08;第4版&#xff09;&#xff08;上下册&#xff09; ​ 系统性总结人工智能的方方面面&#xff0c;…

【C++11】右值引用

右值引用是C11中才被提出来的新概念&#xff0c;而以前的版本中也有引用&#xff0c;但是是指的左值引用。归根结底&#xff0c;左右值引用都是给对象取别名。 1.区分左值和右值 提起左值和右值很多小伙伴可能第一时间会有点小蒙圈&#xff0c;敲了好长时间代码了&#xff0c;对…

详解MySQL数据库索引实现机制 - B树和B+树

详解MySQL数据库索引实现机制 - B树和B树1.索引的出现2.hash算法的缺点3.二叉排序树BST4.平衡二叉树AVL5.红黑树6.B树诞生了7.B树1.索引的出现 索引是一种用于快速查询和检索数据的数据结构&#xff0c;其本质可以看成是一种排序好的数据结构。 索引的作用就相当于书的目录。…