简体   繁体   English

Javascript如何评估“这个”?

[英]How does Javascript evaluate “this”?

I am trying to understand some basic javascript . 我试图了解一些基本的JavaScript。

I have the following snippet. 我有以下代码段。 We have the name variable which in both cases are referenced over getName Method. 我们有name变量,在两种情况下都通过getName方法引用。

First alert outputs HocusPocus , while the second one outputs GeorgeThomas . 第一个警报输出HocusPocus ,而第二个输出GeorgeThomas But I do not understand how this refers to name in this case 但我不明白在这种情况下this是如何引用名称的

  var name = 'Gerorge Thomas'; var obj = { name: 'Cinderella', value: { name: 'HocusPocus', getName: function() { return this.name; } } }; alert( obj.value.getName() ); var testing = obj.value.getName; alert(testing()); 

To understand this issue, you have to understand how Javascript sets the value of this in a function call. 要理解这个问题,您必须了解Javascript如何在函数调用中设置this的值。

There's a summary of all the methods here: When you pass 'this' as an argument 这里有所有方法的摘要: 当你将'this'作为参数传递时

For your particular case, when you do this: 对于您的特定情况,当您这样做时:

var testing = obj.value.getName; 

You now have a reference to the getName function. 您现在可以参考getName函数。 You no longer have any connection at all to obj.value . 您不再与obj.value有任何联系。 So, test() just calls getName as an ordinary function. 因此, test()只是将getName作为普通函数调用。 In Javascript when an ordinary function call is made, then the value of this will be either the global object ( window in a browser) or in strict mode, it will be undefined. 在Javascript中当一个普通的函数调用时,则该值this将或者全局对象( window在浏览器中),或在严格模式时,它是不确定的。

In your case, this becomes the window object so this.name is window.name which points to the global variable name and thus you get the result 'Gerorge Thomas'. 在您的情况下, this将成为window对象,因此this.namewindow.name ,它指向全局变量name ,因此您得到结果'Gerorge Thomas'。

In fact, if you run your code in strict mode, it will cause an error which is, in fact, one of the benefits of strict mode that it points out accidental errors like this. 事实上,如果你在strict模式下运行你的代码,它将导致一个错误,实际上,这是严格模式的一个好处,它指出了这样的意外错误。


On the other hand, if you execute a function with the form of obj.method() , then this is set to be obj . 另一方面,如果以obj.method()的形式执行函数,则将this设置为obj So, when you do: 所以,当你这样做时:

obj.value.getName()

that is equivalent to: 这相当于:

var o = obj.value;
o.getName()

which is the obj.method() form of calling a function which will set the this pointer to be the object, which in this case is obj.value . 这是调用函数的obj.method()形式,它将this指针设置为对象,在本例中为obj.value


It is possible to work around this issue in a couple of ways. 可以通过几种方式解决此问题。 Here's an example of working around it using .bind() . 这是使用.bind()解决它的一个例子。

 var name = 'Gerorge Thomas'; var obj = { name: 'Cinderella', value: { name: 'HocusPocus', getName: function() { return this.name; } } }; document.write( obj.value.getName() + "<br>"); var testing = obj.value.getName.bind(obj.value); document.write(testing()); 

Well it only needs some reflection, let's analyse it: 那么它只需要一些反思,让我们分析一下:

  • In the first alert we are calling the getName() method of the obj.value object so it returns obj.value.name which is "HocusPocus" . 在第一个警报中,我们调用obj.value对象的getName()方法,因此返回obj.value.name ,即"HocusPocus"

alert( obj.value.getName() ); we call this.name where this refers to obj.value so name is HocusPocus 我们将this.name称为obj.value因此名称为HocusPocus

  • But in the second alert we are creating a new function testing() with the body of the getName() method, so it will be attached to the global window object and if we call it we will get the global name value wich is 'Gerorge Thomas' . 但是在第二个警报中,我们正在使用getName()方法的主体创建一个新函数testing() ,因此它将被附加到全局window对象,如果我们调用它,我们将获得全局name值,这是'Gerorge Thomas'

alert(testing()); we are dealing with this.nam e where this refers to the global scope so name is 'Cinderella' . 我们正在处理this.nam e其中this指的是在全球范围内如此的名字是'Cinderella'

First, you're calling a method from inside the obj object. 首先,您从obj对象内部调用方法。 The 2nd time, you're making a copy of the function (not really, it's just a reference) in the global scope. 第二次,你在全局范围内制作了一个功能的副本(不是真的,它只是一个参考)。 So you could also write window.testing() for the 2nd call. 所以你也可以为第二次调用编写window.testing() I think that makes it clear. 我认为这说得很清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM