手机版

分析JS中由此导致的bug

时间:2021-09-02 来源:互联网 编辑:宝哥软件园 浏览:

在js中,这种情况总是不可预测的。在许多情况下,bug总是很混乱。其实你只需要区分不同情况下如何实现。以下是我们为您整理的相关内容:

在JavaScript中,有一个非常特殊的、常用的、经常困扰初学者的东西——“this”,这将在本课中讨论。

这通常指向一个对象,这在不同的情况下指向不同的对象。让我们看几个不同的情况来帮助我们更好地理解“这个”。

窗口对象(全局对象)

这里我们在三种不同的情况下打印“this”,它们直接在函数的外部环境中执行;使用fuction语句执行;使用函数表达式执行(如果函数语句和函数表达式的区别不清楚,请参考注释1)。

因此,会发现这三个“这个”都指向同一个对象,即全局环境的窗口对象(global object):

也就是说,我们可以直接使用这个函数和这个在window对象中创建新的属性:

这里,我们用这个。NewVariable=' . '在窗口对象中创建新属性。在函数的最后,我们可以直接使用console.log(NewVariable)。我们不需要打这个的原因。新变量或窗口。NewVariable这里的意思是我们可以直接使用全局对象(窗口)中的任何属性,而不是使用“.”。

用完的结果会是这样的:

它将打印出我们的“创建新属性”,同时,在大对象窗口中,我们还将找到属性NewVariable:

对象中的方法

我们知道,如果对象中的值是一个基元值(基元类型;例如,字符串、数值、逻辑值),我们将这个新创建的东西称为“property”;如果对象中的值是一个函数,我们将把这个新创建的东西称为“方法”。

在这里,我们将建立方法:

首先,我们以对象文字的方式创建一个对象C,它包含属性名和方法日志。Log是一个匿名函数,函数的内容很简单,就是把这个打印出来(匿名函数参见注释1)。最后,利用c.log语言实现了该方法

让我们看看此时的“这”会是什么。

答案是c对象!

当此函数是对象中的方法时,它将指向包含此方法的对象

JavaScript中的一个bug

让我们进一步看看这个例子:

假设我们在方法日志中添加了这一行。this.name='更新的对象名'

因为我们知道“this”现在指的是对象c,我们可以想象当我执行这个方法时,它会改变c.name的值

这部分没什么问题,但我们继续看。

假设我在方法日志中做了一些更改。在这个方法中,我还创建了一个名为setname的函数,它也使用这个. name=newname来修改这个对象c中name属性的值。

然后执行函数setname,希望将对象c中name的属性值改为“对象c的新名称”,最后打印“这个”看看。

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

仔细看,当我们回头看我们的窗口对象时,我们会发现在窗口对象中发现了一个新的属性“name”,它的值是“object c的New name”。

这是什么意思?意思是这个在函数setname中只是指向了全局对象(窗口对象),而不是刚才的对象C!

在函数setname中,我们使用console.log(这个)来查看:

在log方法中,我们总共执行了console.log(this)三次,结果如下:

第一个和第三个“this”指向对象c,而setname中的第二个“this”指向window对象(全局对象),这就是为什么setname函数不能帮助我们修改对象c中name属性的名称,因为“this”根本不指向对象c。

很多人认为这是JavaScript中的一个bug。

那么我们能做些什么呢

那么遇到上面的例子,我们该怎么做才能避免指向不同的对象呢?

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

第一步

我们在整个函数的顶部添加一行var self=this(有些人会用var that=this)。因为参照的特性,自我和这个指向同一个对象,而这个指向对象c,所以自我指向对象c。

第二步

然后,将方法日志中原来使用的“this”改为“self”,这样可以保证self指向C对象,而不用像上面的例子那样担心指向错误的对象。

如我们所料,在第二个console.log(self)中再次替换了对象c中name属性值。

摘要

我们来总结一下:

如果我们在全局环境中创建一个函数并打印它,那么它将指向全局对象,即窗口对象。

如果我们在一个对象中创建一个函数,也就是说,在一个方法的情况下,这通常会指向包含这个方法的对象(我们说“通用”的原因是因为除了上面的bug情况之外)。

当方法中可能存在您不知道这指向什么的情况时,为了避免不必要的错误,我们可以在方法的顶部创建一个变量,并将其指定为this(var self=this)。

4.如果你真的不知道这在那种情况下会指向什么,就出来看看console.log吧!

示例代码

//function statement function a(){ console . log(this);这个。新变量=“创建新属性”;} a();console . log(NewVariable);var c={ name:'The C object ',log : function(){ var self=this;自我名称='更新的对象名称';console . log(self);var set name=function(new name){ self . name=new name;console . log(self);} setname('对象c的新名称');console . log(self)} } c . log();

版权声明:分析JS中由此导致的bug是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。