2015-09-11 60 views
3

我想了解一些基本的JavaScript。我有以下代码片段。我们有name变量,在这两种情况下都通过getName方法引用。Javascript如何评价“this”?

首先警报输出HocusPocus,而第二个输出GeorgeThomas。但我不知道如何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());

回答

4

要理解这个问题,您必须了解Javascript如何在函数调用中设置this的值。

有这里所有的方法摘要:When you pass 'this' as an argument

为您的特定情况下,当你这样做:

var testing = obj.value.getName; 

您现在可以在getName函数的引用。您根本不再有任何连接到obj.value。因此,test()只是将getName称为普通功能。在Javascript中,当进行普通函数调用时,this的值将是全局对象(在浏览器中为window)或严格模式下,它将是未定义的。

在你的情况,this成为window对象,以便this.namewindow.name指向全局变量name,因此你得到的结果“Gerorge托马斯。

事实上,如果你在strict模式下运行你的代码,它会导致一个错误,实际上它是严格模式的好处之一,它指出了这样的意外错误。


在另一方面,如果你用的obj.method()形式执行的功能,然后this设置为obj。所以,当你这样做:

obj.value.getName() 

,等效于:

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

这是obj.method()形式呼吁将设置this指针为对象,在这种情况下是一个功能obj.value


可以通过几种方法解决此问题。以下是使用.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());

1

首先,你调用从obj对象内部的方法。第二次,你在全局范围内创建函数的副本(不是真的,它只是一个参考)。所以你也可以写第二个电话window.testing()。我认为这很清楚。

+0

是的,它表明谢谢! – deroccha

+0

完全没有函数的副本 - 仍然只有一个函数。有一个函数引用赋值给第二个变量。但是,这项任务与OP的问题无关。问题纯粹是如何调用函数。 – jfriend00

+0

这里没有什么重要的细节,技术细节,但我会听取您的意见。 – DanMan

2

那么它只是需要一些反思,让我们来分析一下:

  • 在第一次警报,我们调用 obj.value对象的getName()方法,因此返回obj.value.name这是 "HocusPocus"

alert(obj.value.getName());我们称之为this.name哪里这是指obj.value这样的名字是HocusPocus

  • 但在第二个提醒,我们正在创造一个新的功能testing()getName()方法的主体,所以它将被附加到 全球window的对象,如果我们称之为我们将获得全球 name的值为'Gerorge Thomas'

alert(testing());我们正在处理this.nam e其中this是指全球范围内所以的名字是'Cinderella'