0

0

JS中this引发bug分析

小云云

小云云

发布时间:2017-12-13 09:22:09

|

1451人浏览过

|

来源于php中文网

原创

在 js 中,this 这个上下文总是变化莫测,很多时候出现bug 总是一头雾水,其实,只要分清楚不同的情况下如何执行就可以了,本文主要介绍了分析javascript中this引发的bug以及相关的处理方法分析,希望能帮助到大家。

在JavaScript中有一个很特别、很常用又常常让初学者很困扰的东西 ─ “this”,在这堂课中会来谈谈这个”this”。

this通常会指向一个对象,同时this会在不同的情境下指向不同的对象。让我们来看几个不同的情境,帮助我们更了解”this”。

window object (global object)

这里我们在三种不同情境去打印”this”,分别是在函数的最外层(outer environment)直接去执行;使用fuction statement去执行;使用function expression去执行(如果还不清楚function statement和function expression的差别,可以参考注1)。


结果会发现,这三个”this”都会指向同样的对象,也就是global environment的window object (global object):


这也就是说,我们可以直接利用这个function和this在window object建立新的属性:

在这里我们利用this.NewVariable = "..."来在window object建立新的属性,函数的最后,我们则可以直接console.log(NewVariable),这里之所以可以不用打this.NewVariable或window.NewVariable是因为任何在global object (window)的属性,我们都可以直接去使用它,而不用使用”.”。


跑出来的结果会像这样子:


它会打印出我们的”Create a new property”,同时,在window这个大的object中,我们也会找到NewVariable这个属性:


method in object

我们知道,在对象里的值如果是原生值(primitive type;例如,字串、数值、逻辑值),我们会把这个新建立的东西称为「属性(property)」;如果对象里面的值是函数(function)的话,我们则会把这个新建立的东西称为「方法(method)」。

在这里,我们就要来建立method:

首先,我们利用object literal的方式创建一个对象c,里面包含属性name和方法log。log是一个匿名函数(anonymous function),函数内容很简单,就是打印this而已(关于匿名函数可参考注1)。最后则是使用c.log的方式来执行该方法。


让我们来看看,这时候的”this”会是什么呢?

答案是对象c!

当这个函数是对象里面的method时,这时候的this就会指向到包含这个method的对象


JavaScript中关于this的一个bug

让我们更进一步延伸来看这个范例:

假设我们在method log裡面多这一行this.name = "Updated Object C name"


因为我们知道”this”现在指的是对象c,所以可以想像的,当我执行这个method的时候,它会去变更c.name的值。


这个部分是没有什么大问题的,不过让我们继续看下去……。

假设我在method log裡面在做一些变更,我在这个method裡面,另外建立一个函数叫做setname,一样是用this.name = newname的方式来修改这个object c中name属性的值。

接着执行setname这个函数,希望把object c中name的属性值改成”New name for object c”,最后再去打印”this”来看一下。


结果我们会发现,对象c中name属性的值并没有变成”New name for object c”,竟然还是一样!?怎么会这样呢?


仔细一看,我们回来看一下我们的window object,我们会发现,在window object中发现了一个新的属性”name”,而且值是”New name for object c”。


这是什么意思呢?意思是原来我们刚刚在函数setname里面的this,指向到的是global object (window object),而不再是刚刚的object C!

ShoopD 网上商店系统
ShoopD 网上商店系统

用 php + mysql 驱动的在线商城系统,我们的目标为中国的中小企业及个人提供最简洁,最安全,最高效的在线商城解决方案,使用了自建的会员积分折扣功能,不同的会员组有不同的折扣,让您的商店吸引更多的后续客户。 系统自动加分处理功能,自动处理会员等级,免去人工处理的工作量,让您的商店运作起来更方便省事 采用了自建的直接模板技术,免去了模板解析时间,提高了代码利用效率 独立开发的购物车系统,使用最

下载


我们在setname这个function中,用console.log(this)来看一下:


在log这个method中,我们一共执行了三次的console.log(this)结果如下:

第一个和第三个”this”指向到的是对象c,而第二个在setname中的this,指向的则是window object (global object),而这也就是为什么setname这个function没办法帮我们修改对象c中name属性的名称,因为”this”根本没指向到对象c。


而许多人都认为,这是JavaScript的一个bug。

那么我们可以怎么做

那么碰到上述的这个例子时,我们可以怎么做来避免指向到不同的对象呢?

许多人的解法是这样的,因为我们知道对象都是用的引用的方式,所以我们可以这样做

STEP 1

我们在整个函数的最上面加上一行var self = this(有些人会用var that = this)。由于引用的特性,self和this会指向到同一个对象,而this指向对象c,所以self一样会指向对象c。

STEP 2

接着,把方法log内原本使用的”this”都改成”self”,这样做可以确保self指向到的是c对象而不用担心会像上面的例子一样指向到错误的对象。


结果也如同我们预期的,在第二次console.log(self)的时候,就再次替换了对象c中name属性的值。


总结

让我们来总结一下:

如果我们是在全局环境建立函数并打印this,这时候this会指向到全局对象,也就是window对象。

如果我们是在对象里面创建函数,也就是方法(method)的情况时,这时候的this一般就会指向到包含这个方法的对象(之所以说”一般”是因为除了上述bug的情况之外)。

碰到method中可能会有不知道this指向到什么的情况时,为了避免不必要的错误,我们可以在method中的最上面建立一个变量,去把它指定成this(var self = this)。

4.如果真的还是不知道那个情况下的this会指向到什么,就console.log出来看看吧!

示例代码


// function statement
function a(){
 console.log(this);
 this.NewVariable = "Create a new property";
}
a();
console.log(NewVariable);
var c = {
 name:"The C object",
 log: function(){
 var self = this;
 self.name = "Updated object C name";
 console.log(self);
 
 var setname = function(newname){
  self.name = newname;
  console.log(self);
 }
 setname("New name for object c");
 console.log(self)
 }
}
c.log();

看完本文之后相信大家对JS中this引发的bug,都有所了解,有需要的赶紧收藏起来吧。

相关推荐:

js中this的理解

JS中this与event的区别详解

js中this的用法实例分析_javascript技巧

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

8

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

6

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

1

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

17

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

18

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号