JAVASCRIPT this关键字详解

2023-10-27

##this指向哪里?

一般而言,this指向函数执行时的当前对象。

In JavaScript, as in most object-oriented programming languages, this
is a special keyword that is used within methods to refer to the
object on which a method is being invoked.

——jQuery Fundamentals (Chapter 2), by Rebecca Murphey

值得注意的是:该关键字在javascript执行环境中,而非声明环境中。

什么意思呢,举例说明:
例1:

	var name = 'window';
	var someone = {
		 name : 'tom',
		 showName : function(){
			 alert(this.name);
		}
	var other = {
		name : 'Bob',
		showName : someone.showName
		}
	other.showName(); //Bob
 结果显示Bob.  this关键字虽然声明在someone.showName,但运行时是在other.showName,所以this指向other对象。所以弹出的是Bob。

##没有明确的当前对象时
在没有明确的运行时对象时,this指向全局对象(global),在浏览器环境中也就是window对象。
By default, this refers to the global object.

为什么说是全局对象(the global
object),因为非浏览器情况下(例如:nodejs)中全局变量并非window对象,而就是叫“全局变量”(the global
object)。

对与this到底指向谁,只要抓准这两点(一般而言,this指向函数执行时的当前对象,当没有明确的当前对象时,this指向全局对象)就可以慢慢弄明白!

例如对于全局变量引用的函数上有:
例2:

var name = 'window';
var Tom = {
		name : 'Tom',
		showName : function(){
			alert(this.name);
		}
	}	
var method = Tom.showName;   //method全局变量
method();  //window

在执行到var method = Tom.showName;这一句的时候,showName是对一个方法的引用(而没有执行),而把这个引用又赋值给了全局变量method。也就是说method指向了方法function(){
alert(this.name);
}
的引用,而method是一个全局变量,所以this指向window对象。
如果它

但是对于局部变量来说:
例3:

var name = 'window';
var Tom = {
		name : 'Tom',
		showName : function(){
			alert(this.name);
		}
	}	
var Bob = {
	name : 'Bob',
	showName : function(){
			var f = Tom.showName;
			f();
		}
	}
	Bob.showName();

在程序执行到Bob.showName();时,showName方法的this指向Bob对象没错,也就是说

function(){
			var f = Tom.showName;
			f();
		}

方法的this指向Bob,如果在
var f = Tom.showName之前加上一句alert(this.name)

function(){
			alert(this.name);  //Bob
			var f = Tom.showName;
			f();
		}

则会弹出’Bob’。
但方法内部方法f的this并不是指向Bob,这里没有明确说明this的指向,所以f方法的this指向window,所以执行f()
结果为’window’

setTimeout、setInterval和匿名函数

在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况
例4:

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){  
        setTimeout(this.showName, 1000);  
    }  
};  

nameObj.waitShowName();

在程序执行到nameObj.waitShowName();这一句时,waitShowName()的this指向nameObj对象,也就是

function(){  
        setTimeout(this.showName, 1000);  
    }  

里的this指向nameObj,所以this.showName才成立,如果这里没有this,而直接写showName则报错。但setTimeout实际调用的就是showName方法,方法体为{alert(this.name)},在调用它的时候没有指定this的指向,所以this指向window。所以最终结果为‘window’。

将代码改成匿名函数可能更好理解一些:
例5:

var name = "window";  
 var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         !function(__callback){
            __callback();
        }(this.showName);  
     }  
 };  
  nameObj.waitShowName();  

在调用nameObj.waitShowName时候,我们运行了一个匿名函数,将this.showName函数作为回调函数传递进这个匿名函数,在匿名函数运行时运行回调函数,因为匿名函数的this指向window,所以当在该匿名函数中运行回调函数时,回调函数的this也指向window。
由此看来
setTimeout、可以看做一个延迟执行的
function (_callback){
_callback();
}
setInterval同理。
如上例,如果一定需要在一秒钟之后显示nameObj 对象的name属性,可以做一些调整

 var name = "window";  
 var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         var that = this;
         setTimeout(function(){
         that.showName();
		},1000);
     }  
 };  
  nameObj.waitShowName();

这样与setTimeout的this指向window并不矛盾。setTimeout执行的具体方法是function(){ that.showName() };
that指向nameObj。并不是showName方法,所以showName方法的this指向就是它的调用者that,也就是nameObj对象。这里体现了最重要的一点:方法嵌套其实很有讲究,this并不能继承到子方法里去。

new关键字

new关键字后的构造函数中的this指向用该构造函数构造出来的新对象。

function Person(_name){
	this.name = _name;
}
Person.prototype.showName = function(){
		alert(this.name);
	}
var tom = new Person('Tom');
tom.showName();  //Tom

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVASCRIPT this关键字详解 的相关文章

  • 设置Tab键为4个空格 Java开发手册规范之tab键设置

    设置Tab键为4个空格 在阿里的Java开发手册 一 编程规约 三 代码格式 第5条提到 强制 采用4个空格缩进 禁止使用tab字符 IDEA中勿勾选 Use tab character eclipse中必选 insert spaces f
  • [JAVEee]SpringBoot项目的创建

    SpringBoot可以更好的开发Spring项目 本文章将使用idea社区版来演示创建项目的过程与注意事项 SpringBoot的优点 SpringBoot中内置快速添加依赖的功能 能够便捷的集成各种框架 帮助开发 内置运行容器 无需配置
  • Linux top里面%CPU和us%的解释

    有的同学会把 CPU和us 搞晕 也就是下图所示在top的时候查看cpu的信息 这时有的同学会问 这两个CPU到底哪个是对的 其实都是对的 只是表达的意思不一样 官方解释如下 Cpu s 34 0 us 用户空间占用CPU百分比 CPU 上
  • 2023华为OD机试真题【最小调整顺序次数】

    问题描述 给定一个队列 但是这个队列比较特殊 可以从头部添加数据 也可以从尾部添加数据 但是只能从头部删除数据 输入一个数字n 会依次添加数字1 n 也就是添加n次 但是在添加数据的过程中 也会删除数据 要求删除必须按照1 n按照顺序进行删

随机推荐

  • 13 二叉树:建立存储结构(前序输入次序) &&二叉树专题

    目录 首先讲讲指针的引用 然后我们再复习一下typedef的用法 然后我们来创建二叉树 二叉树的建立 首先二叉树的存储结构 实际用代码体现 分为顺序存储和链式存储两种 但一般情况我们都用链式存储结构 部分内容转自指针的引用 MAGDB的博客
  • ChatGPT还有哪些不足?

    从技术角度来看 ChatGPT作为一个基于神经网络的自然语言处理模型 其优势在于能够处理大量的语言数据 并生成自然流畅的语言表达 ChatGPT还可以通过对话历史的分析 对当前对话进行上下文感知和情境推理 从而提供更加个性化和智能化的回答
  • Lua 输出可变参数列表内容

    在 Lua 中有8种基本数据类型 nil boolean number string user data function thread table 数据类型 描述 nil 表示一个无效值 boolean 包含两个值 false 和 tru
  • 第三章:关系数据库标准语言SQL

    模式数据定义语言 Schema Data Definition lanuage DDL 外模式数据定义语言 Subschema Data Definition lanuage 外模式DDL 数据存储有关的描述语言 Data storage
  • fedora常用命令

    fedora经验总结 新手必看 一 常用技巧 1 在linux中设置环境变量的方法 如果命令在环境变量已经设置的路径下 在终端命令行输入该命令的文件名和参数 如需要参数 回车即可 如果不在已设路径下 命令前需要加上完整的路径 每次都这样会很
  • Kotlin学习笔记

    1 方法中的参数 有var val 与没有的区别 fun A var name String fun A name String 有var val 表示是当前类的一个属性 无var val 表示是当前方法的一个参数 2 Kotlin中各种声
  • yolov5txt格式的labels转为coco的json格式

    最近在学习ppyoloe 标签文件的格式是coco的json格式 需要把yolov5的txt文件转为json 以下代码即可实现 import os import json import cv2 import random import ti
  • python创建学生类姓名学号_python定义一个学生类,包括学号、姓名和出生日期三个属性(数据成员);包括一个用...

    匿名用户 1级 2018 11 09 回答 import datetime class student def init self Sno Sname Sbarthday Sfaction self Sage 0 self Sgarde 优
  • 代码审计-Java项目&Filter过滤器&CNVD分析&XSS跨站&框架安全

    文章目录 Demo Filter 过滤器引用 Demo ST2框架 组件安全 CNVD Jeesns XSS跨站绕过 CNVD 悟空CRM Fastjson组件 Demo Filter 过滤器引用 Filter Javaweb三大组件之一
  • 【报错】jpa 双向映射导致栈溢出&Jackson的常用注解

    org springframework http converter HttpMessageNotWritableException Could not write JSON Infinite recursion StackOverflow
  • c++ 内存存储 解决char*p, char p[]的问题

    栈 通常用于编译期间就能确定存储大小的变量的存储区 用于在函数作用域内创建 在离开作用域后自动销毁的变量的存储区 有种说法是默认大小1M 堆 通常用于那些在编译期间不能确定存储大小的变量的存储区 它的存储空间是不连续的 一般由malloc
  • python学习—第一步—聪明方法学python

    目录 学习参考资料 遇到的一些小问题 python环境配置与基本语法 python安装与vscode绑定 python常量与变量 常量 变量 python运算符与函数 运算符 函数 局部变量与全局变量 控制流 python数据结构 序列Li
  • Tm4c123GX(tiva)入门详细教程

    TM4C123GX系列 学了几个月的Tiva 总的来说这个款单片机功能还是比较强大的 下面我将以TM4C123GH6PM为例介绍其基本资源及工程建立 点亮板卡上的LED灯以及对基本的时钟配置 PWM uart Timer等方面来做简要说明
  • 使用R语言操作数据框时,我们经常需要创建新的数据列来进行进一步的分析和处理。在本文中,我们将介绍如何通过加和两个数据列来创建一个新的数据列。

    使用R语言操作数据框时 我们经常需要创建新的数据列来进行进一步的分析和处理 在本文中 我们将介绍如何通过加和两个数据列来创建一个新的数据列 要创建新的数据列 我们可以使用mutate 函数以及数据框中的两个已有的数据列 假设我们有一个数据框
  • Vulkan SDK 中的 demo 编译配置 win10 vs2019

    一 下载安装 开始可以简装 然后在打开maintenancetool exe进一步安装其他部件 下载安装 Vulkan SDK Vulkan SDK What s in the SDK Where to Download 会在安装目录中找到
  • 减小内存的占用问题——享元模式和单例模式的对比分析

    前言 接口的常用用法都有什么 策略模式复习总结 的话题提起了 如何解决策略类膨胀的问题 说到 有时候可以通过把依赖于环境Context类的状态保存到客户端里面 而将策略类设计成可共享的 这样策略类实例可以被不同客户端使用 换言之 可以使用享
  • 【前端是什么】

    前端是什么 文章目录 前端是什么 1 前端的概念 2 前端的分类 3 前端的工作流程 4 互联网企业的典型组织结构图 1 前端的概念 1 1 前端的定义 对于网站来说 通常是指网站的前台部分 包括网站的表现层和结构层 通俗点就是用户可以看到
  • 关于STM32的IAP超详细图文解说

    IAP是In Application Programming的首字母缩写 IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写 目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级 以上是IA
  • 【Linux网络编程】传输层udp协议篇

    udp协议篇 一 本篇是在应用篇的后面的 二 传输层 2 1 再谈端口号 2 2 1 两个问题 2 2 2 两个常用命令 2 2 UDP协议 2 2 1 udp协议端格式 理解报头 2 2 2 udp的特点 2 2 3 udp的缓冲区 2
  • JAVASCRIPT this关键字详解

    this指向哪里 一般而言 this指向函数执行时的当前对象 In JavaScript as in most object oriented programming languages this is a special keyword